tabris
tabris copied to clipboard
Swipes to non-zero SwipeItems don't get triggered
Using a Swipe in Tabris for RAP 3.6, I cannot swipe to anything other than the initial 0-indexed page. Swipe events don't get triggered and it never requests the next page.
Example code here: `/* DEMONSTRATES TABRIS TABS - demonstrates swipe bug 2.7 - swipes to other pages never gets triggered */ package bug.snippet;
import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell;
import com.eclipsesource.tabris.widgets.swipe.Swipe; import com.eclipsesource.tabris.widgets.swipe.SwipeContext; import com.eclipsesource.tabris.widgets.swipe.SwipeItem; import com.eclipsesource.tabris.widgets.swipe.SwipeListener;
public class Bugsy { private Display display; private Shell shell; Composite comp; Button butAdd; Button butRemove; Swipe swipe; Label count; MySwipeItemProvider myItemProvider;
public void begin() {
System.out.println("BugSnippy Starting...");
// create the Shell
display = new Display();
shell = new Shell(display, SWT.NONE);
shell.setText("Shell");
shell.setFullScreen(true);
//shell.setBackground(new Color(null, new RGB(255,255,192)));
FormLayout layout = new FormLayout();
shell.setLayout(layout);
FormData fd;
// create the composite
comp = new Composite(shell, SWT.BORDER);
comp.setBackground(new Color(null, 255,0,0));
// set comp's position
fd = new FormData();
fd.left = new FormAttachment(0, 10);
fd.top = new FormAttachment(0, 10);
fd.right = new FormAttachment(100,-10);
fd.bottom = new FormAttachment(75,-10);
comp.setLayoutData(fd);
layout = new FormLayout();
comp.setLayout(layout);
// create the buttons
butAdd = new Button(shell, SWT.PUSH);
butAdd.setText("Add Page");
butRemove = new Button(shell, SWT.PUSH);
butRemove.setText("Remove Page");
// set buttons' position
fd = new FormData();
fd.left = new FormAttachment(0, 10);
fd.top = new FormAttachment(75, 10);
fd.right = new FormAttachment(50,-10);
fd.bottom = new FormAttachment(100,-40);
butAdd.setLayoutData(fd);
fd = new FormData();
fd.left = new FormAttachment(50, 10);
fd.top = new FormAttachment(75, 10);
fd.right = new FormAttachment(100,-10);
fd.bottom = new FormAttachment(100,-40);
butRemove.setLayoutData(fd);
// create the label - shows current count of items in swipe
count = new Label(shell, SWT.NONE);
count.setText("0 swipe items");
fd = new FormData();
fd.left = new FormAttachment(0, 10);
fd.top = new FormAttachment(100, -35);
fd.right = new FormAttachment(100,-10);
fd.bottom = new FormAttachment(100,-5);
count.setLayoutData(fd);
// add the swipe control
myItemProvider = new MySwipeItemProvider();
swipe = new Swipe(comp, myItemProvider);
fd = new FormData();
fd.left = new FormAttachment(0, 5);
fd.top = new FormAttachment(0, 5);
fd.right = new FormAttachment(100,-5);
fd.bottom = new FormAttachment(100,-5);
swipe.getControl().setLayoutData(fd);
butAdd.addListener(SWT.Selection, listenerButAdd);
butRemove.addListener(SWT.Selection, listenerButRemove);
swipe.addSwipeListener(swipeListener);
shell.open();
System.out.println("BugSnippy Done!");
}
SwipeListener swipeListener = new SwipeListener() {
@Override
public void itemLoaded(SwipeItem item, int index) {
}
@Override
public void itemActivated(SwipeItem item, int index, SwipeContext context) {
count.setText(myItemProvider.getItemCount() + " swipe items with activeId: " + myItemProvider.activeItemId);
}
@Override
public void itemDeactivated(SwipeItem item, int index, SwipeContext context) {
}
@Override
public void disposed(SwipeContext context) {
}
};
Listener listenerButAdd = new Listener() {
public void handleEvent(Event event) {
myItemProvider.addItem();
count.setText(myItemProvider.getItemCount() + " swipe items with activeId: " + myItemProvider.activeItemId);
if (myItemProvider.getItemCount() == 1) swipe.show(0);
swipe.refresh();
}
};
Listener listenerButRemove = new Listener() {
public void handleEvent(Event event) {
if (myItemProvider.getItemCount() == 0) return;
System.out.println("REMOVE active: " + myItemProvider.activeItemId + " count: " + myItemProvider.getItemCount());
if (myItemProvider.activeItemId == myItemProvider.getItemCount()) {
// set current page to be 2nd-to-last as we are about to remove the last one
swipe.show(myItemProvider.activeItemId-2);
}
myItemProvider.removeLastItem();
count.setText(myItemProvider.getItemCount() + " swipe items with activeId: " + myItemProvider.activeItemId);
swipe.refresh();
}
};
} `
Problem occurs on iOS. Android seems to swipe OK in most cases.
seems it is not as simple as work/doesn't work... I'll investigate further... maybe related to having other ScrolledComposites on the design
Here are the Swipe classes associated with the above sample:
`package bug.snippet;
import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label;
import com.eclipsesource.tabris.widgets.swipe.SwipeContext; import com.eclipsesource.tabris.widgets.swipe.SwipeItem;
@SuppressWarnings("serial") public class MySwipeItem implements SwipeItem { private Composite comp; public int itemId; public MySwipeItemProvider msip;
public MySwipeItem(int id, MySwipeItemProvider msip) {
itemId = id;
this.msip = msip;
}
@Override
public boolean isPreloadable() {
return(true);
}
@Override
public Control load(Composite parent) {
comp = new Composite(parent, SWT.NONE);
FormData fd = new FormData();
fd.top = new FormAttachment(0, 5);
fd.left = new FormAttachment(0, 5);
fd.bottom = new FormAttachment(100, -5);
fd.right = new FormAttachment(100, -5);
FormLayout layout = new FormLayout();
layout.marginWidth = 0;
layout.marginHeight = 0;
layout.marginLeft = 5;
layout.marginTop = 5;
layout.marginRight = 5;
layout.marginBottom = 5;
layout.spacing = 0;
comp.setLayout(layout);
switch (itemId) {
case 1: comp.setBackground(new Color(null, 0,255,0)); break;
case 2: comp.setBackground(new Color(null, 0,0,255)); break;
case 3: comp.setBackground(new Color(null, 255,0,255)); break;
case 4: comp.setBackground(new Color(null, 255,255,0)); break;
case 5: comp.setBackground(new Color(null, 0,255,255)); break;
case 6: comp.setBackground(new Color(null, 255,127,0)); break;
case 7: comp.setBackground(new Color(null, 255,0,127)); break;
case 8: comp.setBackground(new Color(null, 127,255,0)); break;
case 9: comp.setBackground(new Color(null, 0,255,127)); break;
case 10: comp.setBackground(new Color(null, 127,0,255)); break;
case 11: comp.setBackground(new Color(null, 0,127,255)); break;
default: // item0 and all later pages can just be white
comp.setBackground(new Color(null, 255,255,255)); break;
}
Label lab1 = new Label(comp, SWT.NONE);
lab1.setText("I am a label for page " + itemId);
fd = new FormData();
fd.left = new FormAttachment(0, 10);
fd.top = new FormAttachment(0, 10);
fd.right = new FormAttachment(100,-10);
fd.bottom = new FormAttachment(100,-10);
lab1.setLayoutData(fd);
return(comp);
}
@Override
public void activate(SwipeContext context) {
System.out.println("Activate " + itemId);
msip.activeItemId = itemId;
}
@Override
public void deactivate(SwipeContext context) {
}
} `
... and ...
`package bug.snippet;
import java.util.ArrayList; import java.util.List;
import com.eclipsesource.tabris.widgets.swipe.SwipeItem; import com.eclipsesource.tabris.widgets.swipe.SwipeItemProvider;
@SuppressWarnings("serial") public class MySwipeItemProvider implements SwipeItemProvider { private List<MySwipeItem> items; public int activeItemId;
public MySwipeItemProvider() {
items = new ArrayList<MySwipeItem>();
activeItemId = -1;
}
@Override
public SwipeItem getItem(int index) {
if (items == null) return(null);
if (items.size()-1 >= index) return(items.get(index));
return(null);
}
@Override
public int getItemCount() {
if (items == null) return(0);
return(items.size());
}
public void addItem() {
System.out.println("Add an item. Size before: " + items.size());
items.add(new MySwipeItem(items.size()+1, this));
}
public void removeLastItem() {
System.out.println("Remove an item. Size before: " + items.size());
if (items.size() == 0) return;
items.remove(items.size()-1);
}
} `
A little further investigation has revealed a couple of issues with the sample code, though there are still other issues in our more complex code that I'm trying to understand. In the sample:
-
swipes work OK on Android
-
on iOS, if you ADD a page using the Add Button, this works OK, then add another page and try to swipe to it immediately, it refuses - looks like it doesn't realise there is another page yet. You have to swipe back to the previous page, then onwards 2 swipes to see the new one. This is repeatable - you can add another page, and attempt the swipe to see again. Seems like the iOS client is not getting updated with the new page count.
-
the other issue relates to what happens when you REMOVE a page. In the sample, the Remove Button takes away the final page in the current items and shows the 2nd-to-last page to ensure that the 'current' page is never the one you just removed. This seems to crash the Tabris client on both Android and iOS - not every time, but most of the time.
Ok, figured out the situation to reproduce the original issue... if the SwipeItem is preloadable=false then you simply cannot swipe to any items. Swipe only changes items if preloadable=true.