SLIDER_SCROLLBAR detection of 'scroll buttons'

BlitzMax Forums/MaxGUI Module/SLIDER_SCROLLBAR detection of 'scroll buttons'

remz(Posted 2007) [#1]
Hello!
I have made a very interesting discovery while attempting to detect when the user actually clicks on the small scrolling arrows of a SLIDER_SCROLLBAR in bmax (on Mac, not tested on Windows).

In fact, BlitzMax *does* detect that the user clicked on a scroll button, but it fail to deliver that information back to our program, meaning that as far as we are concerned, the event is exactly the same as if the user scrolled the 'movable knob'. This is not good. It will, in fact, always scroll by a value of 1.

There is also another interesting fact: holding down alt + click on a scroll arrow results in a 'page scroll' instead of a line scroll on Mac OS. (try it in any app, any window). Alas, again, in BMax, this information is lost and not transmitted back to our program.
Note: 'page scroll' does indeed work in Max if you happen to try it inside the code window of MaxGUI itself, or the Home/Code panel, or in the help html view. But these are NOT SLIDER_SCROLLBAR, there are in fact built-in scrollbars tied with the textarea and other controls.

But fear not, there is a very easy way of transmitting the scroll intention of the user with two super small modifications in MaxGUI.
1st modif (optional): cocoa.macos.m This is where we actually need to tell the difference between a 'page scroll' and a 'line scroll'. I choosed arbitrary values of 1 for line scroll, 10 for page scroll. It doesn't matter because your code can intercept the EVENT_GADGETACTION in a hook and do something adequate.
-(void)scrollerSelect:(id)sender{
	NSScroller *scroller;
	Int delta=0;
	scroller=(NSScroller *)sender;
	switch([scroller hitPart]){
	Case NSScrollerDecrementLine:
		delta=-1;
		break;
	Case NSScrollerDecrementPage:
		delta=-10;
		break;
	Case NSScrollerIncrementLine:
		delta=1;
		break;	
	Case NSScrollerIncrementPage:
		delta=10;
		break;	
	}
PostGuiEvent(BBEVENT_GADGETACTION,sender,delta,0,0,0,0 );
}


2nd modif: cocoagui.bmx
	If id=EVENT_GADGETACTION
		Select gadget.class
			Case GADGET_SLIDER
				If data Then
					gadget.SetProp(gadget.GetProp()+data)
					x=data ' x field holds the delta movement from a scroll button (Mac)
				End If
				data=gadget.GetProp()

So the only thing we've added here is x=data: this will allow the code to detect that is Event.X is not 0, we now know that the user clicked on a scroll button. If the value is 1 or -1, it's a normal line-scroll. If it's 10 or -10, then it's a page scroll.

I'm happy, it works in my Image Browser app :)


DavidDC(Posted 2007) [#2]
Thanks for posting this remz.

You're right - this is an event Max should know about. I haven't tried this yet, but I'm wondering how you distinguish between a manual slider bar movement of 10 and a page scroll, if you were looking to set your own custom scroll leaps?

- David


remz(Posted 2007) [#3]
..but I'm wondering how you distinguish between a manual slider bar movement of 10 and a page scroll..

Yes DavidDC: you can because the delta you read in Event.X is only set when the user clicks on a scroll button. When the user manually drag the knob, only 'data' changes, so Event.X = 0.

However, in order to be a full-featured addition to MaxGUI, I think we would need to create a new function called something like SetSliderDelta(Slider:TGadget, Line:Value, Page:Value) that would allow the programmer to set a custom scroll speed for both line and page scrolling.


DavidDC(Posted 2007) [#4]
Ah OK, great. Thanks remz!

- David


remz(Posted 2007) [#5]
I just checked the default behavior on Win32: 'line scroll' scrolls by 1 exactly as the Mac, but 'page scroll' works dirrently: on Mac, page scroll also scrolls by 1. On Win32, page scroll on a scroll bar (which is done by clicking inside the scroll bar, on the left or right of the scroll knob.)
The page scroll amount is actually calculated as the 'visible' part when calling SetSliderRange(). You can see it with in code from win32slider.cpp
		info.nPage=visible;
		SetScrollInfo( _gadget.hwnd(),SB_CTL,&info,true );

So in order to be able to catch 'line scroll' and 'page scroll' event from EVENT_GADGETACTION like I posted for the Mac, you just have to modify this function a little bit:
LRESULT Win32Slider::wndProc( HWND hwnd,UINT msg,WPARAM wp,LPARAM lp,WNDPROC proc ){

	SCROLLINFO info={sizeof(info)};
	int event_x = 0;
...
		switch( LOWORD(wp) ){
			case SB_LINELEFT:
				event_x = -1;
				break;
			case SB_PAGELEFT:
				event_x = -10;
				break;
			case SB_LINERIGHT:
				event_x = 1;
				break;
			case SB_PAGERIGHT:
				event_x = 10;
				break;
				
			case SB_THUMBTRACK:
			case SB_THUMBPOSITION:
...
	}
	emit( BBEVENT_GADGETACTION,value(),0,event_x );
	return 0;
}

I hope that this can help :)
Note: again, the preferable way to do this modification would be to have a new method 'SetSliderDelta' or similar that would allow the user to customize line and page scrolling value, but in any case it could be useful to be able to differenciate them from regular 'scroll bar dragging' scroll.


Impi(Posted 2011) [#6]
Hello!

I know this is a old thread. Is it possible to detect 'scroll buttons' in MaxGui now?
Thanks!


jsp(Posted 2011) [#7]
Yes, using the EVENT_GADGETACTION.
It changes the slider value by 1, plus or minus.

But there is no extra event for the buttons.

Last edited 2011


Impi(Posted 2011) [#8]
Thanks! This is a useful workaround. I can check if the slider value changes only by 1. Because this is nearly impossible by moving the scrollbar (I want to scroll a big bitmap) I can be fairly sure one of the buttons has been clicked.

Btw your Logic Gui looks very interesting.

Last edited 2011

Last edited 2011


jsp(Posted 2011) [#9]
Yes, it is only a workaround, if you want to act directly onto the scroll-button-click.
If you like to speed up the scrolling when pushed you could change the value yourself to a reasonable size.


Btw your Logic Gui looks very interesting.


Thanks! Many features and work has gone into it and it will save a lot of time when coding tools and applications and such.