Bug 402732 - selection events on scrollbar not detected
Summary: selection events on scrollbar not detected
Status: CLOSED DUPLICATE of bug 393269
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.2.1   Edit
Hardware: PC Linux
: P3 major with 4 votes (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords: triaged
Depends on: 510538
Blocks:
  Show dependency tree
 
Reported: 2013-03-08 07:30 EST by Chandrayya CLA
Modified: 2019-09-12 10:25 EDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chandrayya CLA 2013-03-08 07:30:06 EST
Using the below code I tried to detect the mouse events on scrollbar like click on right, left arrow button, dragging the thumb and page up page down events(When clicked on the area between thumb and right or left arrow button).

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;

public class Scroll {
    static int shellStyle = SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND |  SWT.CLOSE | SWT.RESIZE;
    static int canvasStyle = SWT.NO_REDRAW_RESIZE | SWT.H_SCROLL | SWT.V_SCROLL;

    public static void main(String[] args) {
        final Display display = new Display();
        final Shell shell = new Shell(display, shellStyle);
        shell.setLayout(new FillLayout());
        shell.setBackground(display.getSystemColor((SWT.COLOR_CYAN)));
        shell.setText("Canvas Test");
        shell.setSize(400, 300);

        Composite composite = new Composite(shell, SWT.NONE);
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        composite.setLayout(new GridLayout(1, false));

        final Canvas canvas = new Canvas(composite, canvasStyle);
        canvas.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
        canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

        final ScrollBar hBar = canvas.getHorizontalBar();
        hBar.setMaximum(2120);
        hBar.setMinimum(0);
        hBar.addListener(SWT.Selection, new Listener() {

            @Override
            public void handleEvent(Event event) {
                System.out.println("Mouse events details on Scrollbar");
                switch (event.detail) {
                case SWT.DragDetect:
                    System.out.println("drag detected");
                    break;
                case SWT.DRAG:
                    System.out.println("drag");
                    break;
                case SWT.PAGE_UP:
                    System.out.println("Page up");
                    break;
                case SWT.PAGE_DOWN:
                    System.out.println("Page down");
                    break;
                case SWT.ARROW_DOWN:
                    System.out.println("arrow down");
                    break;
                case SWT.ARROW_UP:
                    System.out.println("arrow up");
                    break;
                case SWT.ARROW_LEFT:
                    System.out.println("arrow left");
                    break;
                case SWT.ARROW_RIGHT:
                    System.out.println("arrow right");
                    break;
                }
            }

        });
        // Create a paint handler for the canvas
        canvas.addPaintListener(new PaintListener() {
            @Override
            public void paintControl(PaintEvent e) {
                e.gc.drawString("Scroll bar events are not detected", 0, 10);
            }

        });
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();

    }
}

But Iam not able to detect these events. I have also seen that similar bug was raised (https://bugs.eclipse.org/bugs/show_bug.cgi?id=51995) before and it was fixed. I am using GTK+ 2.24(Ubuntu 12.04). But it is not working for me.

Kindly mention the steps to detect the mouse events on scrollbars.
Comment 1 Konstantin F. CLA 2013-07-30 07:12:48 EDT
Hey,

I also having the same issue with Eclipse Kepler (4.3). I tried the following example from http://www.eclipse.org/swt/snippets.

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.*;

public class Snippet17 {

public static void main (String [] args) {
	Display display = new Display ();
	Shell shell = new Shell (display);
	Slider slider = new Slider (shell, SWT.HORIZONTAL);
	Rectangle clientArea = shell.getClientArea ();
	slider.setBounds (clientArea.x + 10, clientArea.y + 10, 200, 32);
	slider.addListener (SWT.Selection, new Listener () {
		public void handleEvent (Event event) {
			String string = "SWT.NONE";
			switch (event.detail) {
				case SWT.DRAG: string = "SWT.DRAG"; break;
				case SWT.HOME: string = "SWT.HOME"; break;
				case SWT.END: string = "SWT.END"; break;
				case SWT.ARROW_DOWN: string = "SWT.ARROW_DOWN"; break;
				case SWT.ARROW_UP: string = "SWT.ARROW_UP"; break;
				case SWT.PAGE_DOWN: string = "SWT.PAGE_DOWN"; break;
				case SWT.PAGE_UP: string = "SWT.PAGE_UP"; break;
			}
			System.out.println ("Scroll detail -> " + string);
		}
	});
	shell.open ();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch ()) display.sleep ();
	}
	display.dispose ();
}
} 

I'm always getting "SWT.NONE". Is there any workaround for this? I'm using Ubuntu 12.04. Thank you.

Kon
Comment 2 Chandrayya CLA 2013-07-31 02:21:32 EDT
Yes this problem is also with Slider.

Workaround:
Set the page increment and increment values to Slider or Scrollbar.
sbr.setPageIncrement(100);//Scrollbar will be moved 100 pixel back or forth when clicked on area between thumb and left arrow button or area between thumb and right arrow button.

sbr.setIncrement(10); //Scrollbar will be moved 10 pixel back or forth when clicked on left or right arrow button.

Add the below code in scrollbar or slider selection listener

sbr.addListener(SWT.Selection, new Listener() {
 @Override
 public void handleEvent(Event event) {
      int hSelection = sbr.getSelection();
      if (hSelection - prevHselection == -sbr.getIncrement()) {
        System.out.println("clicked right arrow button");
      } else if (hSelection - prevHselection == sbr.getIncrement()) {
        System.out.println("clicked left arrow button");
      } else if (hSelection - prevHselection == -sbr.getPageIncrement()) {
        System.out.println("clicked on area between thumb and right arrow  button");              
      } else if (hSelection - prevHselection == sbr.getPageIncrement()) 
        System.out.println("clicked on area between thumb and left arrow  button");   
      } else if(hSelection - prevHselection > 0){
         System.out.println("Thumb is dragged forward");                 
      } else if(hSelection - prevHselection < 0){
         System.out.println("Thumb is dragged backward");                 
      }
     prevHselection = hSelection; //create field prevSelection
 }
}
Note AFTER client resize update page increment and increment values.
Comment 3 Chandrayya CLA 2013-07-31 02:32:24 EDT
(In reply to comment #2)
> Yes this problem is also with Slider.
> 
> Workaround:
> Set the page increment and increment values to Slider or Scrollbar.
> sbr.setPageIncrement(100);//Scrollbar will be moved 100 pixel back or forth
> when clicked on area between thumb and left arrow button or area between
> thumb and right arrow button.
> 
> sbr.setIncrement(10); //Scrollbar will be moved 10 pixel back or forth when
> clicked on left or right arrow button.
> 
> Add the below code in scrollbar or slider selection listener
> 
> sbr.addListener(SWT.Selection, new Listener() {
>  @Override
>  public void handleEvent(Event event) {
>       int hSelection = sbr.getSelection();
>       if (hSelection - prevHselection == sbr.getIncrement()) {
>         System.out.println("clicked right arrow button");
>       } else if (hSelection - prevHselection == -sbr.getIncrement()) {
>         System.out.println("clicked left arrow button");
>       } else if (hSelection - prevHselection == sbr.getPageIncrement()) {
>         System.out.println("clicked on area between thumb and right arrow 
> button");              
>       } else if (hSelection - prevHselection == -sbr.getPageIncrement()) 
>         System.out.println("clicked on area between thumb and left arrow 
> button");   
>       } else if(hSelection - prevHselection > 0){
>          System.out.println("Thumb is dragged forward");                 
>       } else if(hSelection - prevHselection < 0){
>          System.out.println("Thumb is dragged backward");                 
>       }
>      prevHselection = hSelection; //create field prevSelection
>  }
> }
> Note AFTER client resize update page increment and increment values.
==Changed conditions appropriately
Comment 4 Pavel Matveev CLA 2014-07-15 10:01:23 EDT
you can modify method long /* int */windowProc(long /* int */handle, long /* int */arg0, long /* int */arg1, long /* int */arg2, long /* int */user_data) in org.eclipse.swt.widgets.Widget:

original:
long /* int */windowProc(long /* int */handle, long /* int */arg0,
            long /* int */arg1, long /* int */arg2, long /* int */user_data) {
        switch ((int) /* 64 */user_data) {
        case CHANGE_VALUE:
            return gtk_change_value(handle, arg0, arg1, arg2);
        case EXPAND_COLLAPSE_CURSOR_ROW:
            return gtk_expand_collapse_cursor_row(handle, arg0, arg1, arg2);
        case INSERT_TEXT:
            return gtk_insert_text(handle, arg0, arg1, arg2);
        case TEXT_BUFFER_INSERT_TEXT:
            return gtk_text_buffer_insert_text(handle, arg0, arg1, arg2);
        default:
	    return 0;
        }
    }

modified:
long /* int */windowProc(long /* int */handle, long /* int */arg0,
            long /* int */arg1, long /* int */arg2, long /* int */user_data) {
        switch ((int) /* 64 */user_data) {
        case CHANGE_VALUE:
            return gtk_change_value(handle, arg0, arg1, arg2);
        case EXPAND_COLLAPSE_CURSOR_ROW:
            return gtk_expand_collapse_cursor_row(handle, arg0, arg1, arg2);
        case INSERT_TEXT:
            return gtk_insert_text(handle, arg0, arg1, arg2);
        case TEXT_BUFFER_INSERT_TEXT:
            return gtk_text_buffer_insert_text(handle, arg0, arg1, arg2);
        default:
            switch ((int) arg1) {
            case CHANGE_VALUE:
                return gtk_change_value(handle, arg0, arg1, arg2);
            default:
                return 0;
            }
        }
    }

I don't know why, but CHANGE_VALUE set in arg1 instead user_data

it is working for Centos 6.4 eclipse 3.6,3.7,3.8,4.3.2,4.4.0
Comment 5 Jesper Eskilson CLA 2016-12-16 05:30:56 EST
This looks like a regression of bug 51995.
Comment 6 Eric Williams CLA 2019-02-01 13:47:53 EST
Still reproducible with SWT master as of today, GTK3.24, and Fedora 29.
Comment 7 Eric Williams CLA 2019-09-11 14:23:19 EDT
GtkRange's "change-value" callback method has a gdouble as a parameter, and I believe this is causing the issue here. Once we implement proper support for doubles in callbacks we should be fine.
Comment 8 Eric Williams CLA 2019-09-12 10:25:17 EDT
In the meantime we can implement a custom Callback, since we aren't using the double value. I'll do this in bug 393269.

*** This bug has been marked as a duplicate of bug 393269 ***