From 798edf80a978b6357147f5c38b7e817b5373d432 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Fri, 3 Feb 2012 15:00:39 +0000 Subject: [PATCH] #8284, #8336 Fixed header and footer click for right and middle click. Browser context menu is also disabled on right click when there is a click listener. svn changeset:22887/svn branch:6.7 --- src/com/vaadin/terminal/gwt/client/Util.java | 14 ++ .../terminal/gwt/client/ui/VScrollTable.java | 51 ++++-- .../HeaderFooterClickLeftRightMiddle.html | 92 +++++++++++ .../HeaderFooterClickLeftRightMiddle.java | 154 ++++++++++++++++++ 4 files changed, 294 insertions(+), 17 deletions(-) create mode 100644 tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html create mode 100644 tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java diff --git a/src/com/vaadin/terminal/gwt/client/Util.java b/src/com/vaadin/terminal/gwt/client/Util.java index 3dbbd22329..60afcc2839 100644 --- a/src/com/vaadin/terminal/gwt/client/Util.java +++ b/src/com/vaadin/terminal/gwt/client/Util.java @@ -1321,4 +1321,18 @@ public class Util { cur = cur.parentNode; } }-*/; + + /** + * Checks if the given event is either a touch event or caused by the left + * mouse button + * + * @param event + * @return true if the event is a touch event or caused by the left mouse + * button, false otherwise + */ + public static boolean isTouchEventOrLeftMouseButton(Event event) { + int eventType = event.getTypeInt(); + boolean touchEvent = Util.isTouchEvent(event); + return touchEvent || event.getButton() == Event.BUTTON_LEFT; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java index f7d23d4453..cff25e00bf 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java @@ -2338,7 +2338,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, DOM.appendChild(td, captionContainer); - DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.TOUCHEVENTS); + DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK + | Event.ONCONTEXTMENU | Event.TOUCHEVENTS); setElement(td); @@ -2455,8 +2456,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, scrollBodyPanel.setFocus(true); } handleCaptionEvent(event); - event.stopPropagation(); - event.preventDefault(); + boolean stopPropagation = true; + if (event.getTypeInt() == Event.ONCONTEXTMENU + && !client.hasEventListeners(VScrollTable.this, + HEADER_CLICK_EVENT_ID)) { + // Prevent showing the browser's context menu only when + // there is a header click listener. + stopPropagation = false; + } + if (stopPropagation) { + event.stopPropagation(); + event.preventDefault(); + } } } } @@ -2513,7 +2524,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, switch (DOM.eventGetType(event)) { case Event.ONTOUCHSTART: case Event.ONMOUSEDOWN: - if (columnReordering) { + if (columnReordering + && Util.isTouchEventOrLeftMouseButton(event)) { if (event.getTypeInt() == Event.ONTOUCHSTART) { /* * prevent using this event in e.g. scrolling @@ -2532,7 +2544,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, case Event.ONMOUSEUP: case Event.ONTOUCHEND: case Event.ONTOUCHCANCEL: - if (columnReordering) { + if (columnReordering + && Util.isTouchEventOrLeftMouseButton(event)) { dragging = false; DOM.releaseCapture(getElement()); if (moved) { @@ -2592,14 +2605,6 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, break; } break; - case Event.ONCONTEXTMENU: - if (client.hasEventListeners(VScrollTable.this, - HEADER_CLICK_EVENT_ID)) { - // Prevent showing the browser's context menu when there is - // a right click listener. - event.preventDefault(); - } - break; case Event.ONDBLCLICK: fireHeaderClickedEvent(event); break; @@ -3338,7 +3343,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, DOM.appendChild(td, captionContainer); - DOM.sinkEvents(td, Event.MOUSEEVENTS); + DOM.sinkEvents(td, Event.MOUSEEVENTS | Event.ONDBLCLICK + | Event.ONCONTEXTMENU); setElement(td); } @@ -3523,8 +3529,18 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, if (DOM.eventGetType(event) == Event.ONMOUSEUP) { scrollBodyPanel.setFocus(true); } - event.stopPropagation(); - event.preventDefault(); + boolean stopPropagation = true; + if (event.getTypeInt() == Event.ONCONTEXTMENU + && !client.hasEventListeners(VScrollTable.this, + FOOTER_CLICK_EVENT_ID)) { + // Show browser context menu if a footer click listener is + // not present + stopPropagation = false; + } + if (stopPropagation) { + event.stopPropagation(); + event.preventDefault(); + } } } @@ -3535,7 +3551,8 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler, * The event to handle */ protected void handleCaptionEvent(Event event) { - if (DOM.eventGetType(event) == Event.ONMOUSEUP) { + if (event.getTypeInt() == Event.ONMOUSEUP + || event.getTypeInt() == Event.ONDBLCLICK) { fireFooterClickedEvent(event); } } diff --git a/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html new file mode 100644 index 0000000000..1ab1c61e88 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.html @@ -0,0 +1,92 @@ + + + + + + +New Test + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
New Test
open/run/com.vaadin.tests.components.table.HeaderFooterClickLeftRightMiddle?restartApplication
mouseClickvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]59,8
assertTextvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_01. Click on header col1 using left
mouseDownRightvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]
mouseUpRightvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]
assertTextvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_02. Click on header col1 using right
doubleClickvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[2]
assertTextvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_03. Double click on header col1 using left
mouseClickvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]59,8
assertTextvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_04. Click on footer col2 using left
mouseDownRightvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]
mouseUpRightvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]
assertTextvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_05. Click on footer col2 using right
doubleClickvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[5]/VScrollTable[0]/domChild[2]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[0]/domChild[1]
assertTextvaadin=runcomvaadintestscomponentstableHeaderFooterClickLeftRightMiddle::PID_SLog_row_06. Double click on footer col2 using left
+ + diff --git a/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java new file mode 100644 index 0000000000..642067d826 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/table/HeaderFooterClickLeftRightMiddle.java @@ -0,0 +1,154 @@ +package com.vaadin.tests.components.table; + +import com.vaadin.data.Container; +import com.vaadin.data.Item; +import com.vaadin.data.Property.ValueChangeEvent; +import com.vaadin.data.Property.ValueChangeListener; +import com.vaadin.data.util.IndexedContainer; +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.Log; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Button.ClickListener; +import com.vaadin.ui.CheckBox; +import com.vaadin.ui.Table; +import com.vaadin.ui.Table.FooterClickEvent; +import com.vaadin.ui.Table.FooterClickListener; +import com.vaadin.ui.Table.HeaderClickEvent; +import com.vaadin.ui.Table.HeaderClickListener; + +public class HeaderFooterClickLeftRightMiddle extends TestBase { + + private Log log = new Log(10); + + @Override + protected void setup() { + final Table table = new Table(); + table.setColumnReorderingAllowed(true); + table.setContainerDataSource(createContainer()); + table.setWidth("400px"); + table.setHeight("400px"); + table.setImmediate(true); + table.setFooterVisible(true); + + CheckBox immediateCheckbox = new CheckBox("Immediate"); + immediateCheckbox.setImmediate(true); + immediateCheckbox.setValue(table.isImmediate()); + immediateCheckbox.addListener(new ClickListener() { + + public void buttonClick(ClickEvent event) { + table.setImmediate(event.getButton().booleanValue()); + } + }); + + CheckBox headerClickListenerCheckbox = new CheckBox( + "Header click listener"); + headerClickListenerCheckbox.setImmediate(true); + headerClickListenerCheckbox.addListener(new ValueChangeListener() { + + private HeaderClickListener headerClickListener = new HeaderClickListener() { + + public void headerClick(HeaderClickEvent event) { + String type = event.isDoubleClick() ? "Double click" + : "Click"; + log.log(type + " on header " + + event.getPropertyId().toString() + " using " + + event.getButtonName()); + } + + }; + + public void valueChange(ValueChangeEvent event) { + if (table.getListeners(HeaderClickEvent.class).isEmpty()) { + table.addListener(headerClickListener); + } else { + table.removeListener(headerClickListener); + } + } + }); + headerClickListenerCheckbox.setValue(true); + + CheckBox footerClickListenerCheckbox = new CheckBox( + "Footer click listener"); + footerClickListenerCheckbox.setImmediate(true); + footerClickListenerCheckbox.addListener(new ValueChangeListener() { + + private FooterClickListener footerClickListener = new FooterClickListener() { + + public void footerClick(FooterClickEvent event) { + String type = event.isDoubleClick() ? "Double click" + : "Click"; + log.log(type + " on footer " + + event.getPropertyId().toString() + " using " + + event.getButtonName()); + } + }; + + public void valueChange(ValueChangeEvent event) { + if (table.getListeners(FooterClickEvent.class).isEmpty()) { + table.addListener(footerClickListener); + } else { + table.removeListener(footerClickListener); + } + } + }); + footerClickListenerCheckbox.setValue(true); + + CheckBox sortEnabledCheckbox = new CheckBox("Sortable"); + sortEnabledCheckbox.setImmediate(true); + sortEnabledCheckbox.setValue(!table.isSortDisabled()); + sortEnabledCheckbox.addListener(new ClickListener() { + + public void buttonClick(ClickEvent event) { + table.setSortDisabled(!event.getButton().booleanValue()); + } + }); + + CheckBox columnReorderingCheckbox = new CheckBox( + "Column reordering allowed"); + columnReorderingCheckbox.setImmediate(true); + columnReorderingCheckbox.setValue(table.isColumnReorderingAllowed()); + columnReorderingCheckbox.addListener(new ClickListener() { + + public void buttonClick(ClickEvent event) { + table.setColumnReorderingAllowed(event.getButton() + .booleanValue()); + } + }); + + addComponent(immediateCheckbox); + addComponent(headerClickListenerCheckbox); + addComponent(footerClickListenerCheckbox); + addComponent(sortEnabledCheckbox); + addComponent(columnReorderingCheckbox); + addComponent(table); + addComponent(log); + + } + + @Override + protected String getDescription() { + return "Tests the header click listener"; + } + + @Override + protected Integer getTicketNumber() { + return 4515; + } + + private Container createContainer() { + IndexedContainer container = new IndexedContainer(); + container.addContainerProperty("col1", String.class, ""); + container.addContainerProperty("col2", String.class, ""); + container.addContainerProperty("col3", String.class, ""); + + for (int i = 0; i < 100; i++) { + Item item = container.addItem("item " + i); + item.getItemProperty("col1").setValue("first" + i); + item.getItemProperty("col2").setValue("middle" + i); + item.getItemProperty("col3").setValue("last" + i); + } + + return container; + } + +} -- 2.39.5