tabris icon indicating copy to clipboard operation
tabris copied to clipboard

Swipes to non-zero SwipeItems don't get triggered

Open JohnGymer opened this issue 5 years ago • 4 comments

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.

JohnGymer avatar Apr 25 '19 11:04 JohnGymer

seems it is not as simple as work/doesn't work... I'll investigate further... maybe related to having other ScrolledComposites on the design

JohnGymer avatar Apr 25 '19 12:04 JohnGymer

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);
}

} `

JohnGymer avatar Apr 25 '19 12:04 JohnGymer

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.

JohnGymer avatar Apr 25 '19 12:04 JohnGymer

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.

JohnGymer avatar Apr 25 '19 14:04 JohnGymer