My slider control code not working properly .

Started by NRJ, July 16, 2018, 09:34:48

Previous topic - Next topic

NRJ

Below is the code for the slider control ,but it is not working properly ,if I move the mouse quickly ,it looses the control over the slider circle .Any better way to achieve this ?







Graphics 800,600
AutoMidHandle True

Global mp:TImage=LoadImage("pointer.png")
Global sliderframe:TImage=LoadImage("sliderframe.png")
Global scntrl:TImage=LoadImage("scntrl.png")

Global px:Int=166
Global mx:Int,my:Int


HideMouse()
While Not KeyHit(key_escape)
Cls
SetBlend alphablend
mx=MouseX()
my=MouseY()

draw_slider()
update_slider()

DrawText px,10,10
DrawImage mp,mx,my
Flip
Wend
End

Function draw_slider()
DrawImage sliderframe,400,300
DrawImage scntrl,px,300
End Function

Function update_slider()
If MouseDown(1) Then
If ImagesCollide(mp,mx,my,0,scntrl,px,300,0) Then
px=MouseX()

If px<166 Then px=166
If px>634 Then px=634
EndIf
EndIf
End Function
IF YOU CAN DREAM IT,  YOU CAN DO IT...

http://www.nksoftgames.blogspot.com

TomToad

This is because the mouse moves further in one frame than the width of the slider, so ImagesCollide() fails.  You need to set a flag to detect when the mouse is held down.

Code (blitzmax) Select
Graphics 800,600
AutoMidHandle True

Global mp:TImage=LoadImage("pointer.png")
Global sliderframe:TImage=LoadImage("sliderframe.png")
Global scntrl:TImage=LoadImage("scntrl.png")

Global px:Int=166
Global mx:Int,my:Int


HideMouse()
While Not KeyHit(key_escape)
Cls
SetBlend alphablend
mx=MouseX()
my=MouseY()

draw_slider()
update_slider()

DrawText px,10,10
DrawImage mp,mx,my
Flip
Wend
End

Function draw_slider()
DrawImage sliderframe,400,300
DrawImage scntrl,px,300
End Function

Function update_slider()
Global MouseFlag:Int = False

If MouseFlag
If MouseDown(1) Then
px=MouseX()

If px<166 Then px=166
If px>634 Then px=634
Else
MouseFlag = False
EndIf
Else
If MouseDown(1) And ImagesCollide(mp,mx,my,0,scntrl,px,300,0)
MouseFlag = True
EndIf
EndIf
End Function
------------------------------------------------
8 rabbits equals 1 rabbyte.

Holzchopf

Ah yes, the typical mouse-leaves-handle problem.

Simplest solution:

1) Add a global that tells if the slider is currently grabbed or not. E.g: Global slidergrabbed:Int
2) Set this global to true, when you first start grabbing the slider handle.
3) Change the expression that checks if the slider is grabbed, so that not only colliding the mouse with the handle fires true but also when slidergrabbed is.
4) Unset slidergrabbed whenever you want the slider to stop respond. This could be the case when another gadget gets focus, the program is suspended or at least when the mouse is released, e.g: Function update_slider()
If MouseDown(1) Then
If ImagesCollide(mp,mx,my,0,scntrl,px,300,0) Or slidergrabbed Then
slidergrabbed = True
px=MouseX()

If px<166 Then px=166
If px>634 Then px=634
Endif
Else
slidergrabbed = False
EndIf
End Function



NRJ

Thank you TomToad and Holzchopf ,now it is working fine.
IF YOU CAN DREAM IT,  YOU CAN DO IT...

http://www.nksoftgames.blogspot.com

Derron

@ globals

GUI widgets should not need globals for individual widget stuff. Widgets need to know whether they are focused (eg. mouse clicked in input field, or slider is active - means a cursor-right-left should move the slider handle...). They also need to know about click events (eg. one clicked on the gauge of the slider widget to directly jump to a value).
Sliders need to store if their handle is pressed now. So this sounds similar to what holzchopf wrote. BUT ... you do not need to have a "is a slider handle pressed" global, nope - you need to understand what it means "input wise". If your widget handled the "mouse is down" then _this_ should be marked somewhere so to avoid that further processed widgets are also reacting to a kept-down mouse button (imagine you are pressing the slider handle and then are moving the mouse cursor over another button - or another slider).

So instead of requiring other widgets (or a "widget manager"-master) to know about the slider class itself ("if not sliderhandlepressed then ...") you handle the input - which was the original source of the "pressed handle"-action happening in this logic cycle/loop. This allows for widgets to stay independend from each other - or from polluting a "main type" with widget-specific stuff.


bye
Ron