Michael,
I was misled by the subject line. I thought you were designing a Radio button control.
What we have here are check box like controls shaped like a radio button.
In that context my earlier remarks make no sense as we were thinking of different things.
Ciao,
Z
Radio Button tool (on/off) (New)
Re: Radio Button tool (on/off) (New)
oh I see. Maybe I don't know how a radio button should work.. hmmm .. I did some checking.. ok.. a radio button would normally be in a group and only one of the group could be active.. I will see if I can modify it to be either a check box style or a group of radio buttons working as it is normally used.
Re: Radio Button tool (on/off) (New)
Hi, Michael,
Now we agree on what a radio button should do here is a little no frills demo that should work in all flavours of BBC BASIC.
Edit by Z. Perhaps I should add since no one else has that SDL and BB4W have perfectly good libraries for this function of button already. But if you still feel the need to roll your own ...
It is just one of a myriad ways you could do this. I used an array of structures so it is easy to hold all the control data in an initialization part and not have it hard coded. It is easily changed to have more or fewer controls or even different types of control. Some might argue that a linked list would be better but I decided to save that for another day or others to code. The structure saves the status so you don't have to worry about TINT not working: you can color it anything you want. It uses very little CPU time.
I hope this gives you or others some ideas that you can build on.
UPDATE: I have "improved" this adding the highlighting when there is a mouse over, and separating out the drawing part so that you can easily modify the button shape. It uses more CPU time so I have tried to avoid unnecessary redrawing. Here goes:
Z
Now we agree on what a radio button should do here is a little no frills demo that should work in all flavours of BBC BASIC.
Edit by Z. Perhaps I should add since no one else has that SDL and BB4W have perfectly good libraries for this function of button already. But if you still feel the need to roll your own ...
Code: Select all
MODE 8
VDU 5
OFF
REM Define buttons and initial state.
DIM RB{(5) x%, y%, state%, text$}
DATA 100,100,1,"One",100,200,0,"Two",100,300,0,"Three",100,400,0,"Four",100,500,0,"Five",100,600,0,"Six"
REM Display buttons
FOR I%=0 TO DIM(RB{()},1)
READ RB{(I%)}.x%, RB{(I%)}.y%, RB{(I%)}.state%, RB{(I%)}.text$
PROCdraw(RB{()},I%)
NEXT
REM Check for mouse over button and click
OldB%=0
REPEAT
REM Main program loop
MOUSE X%,Y%,B%
IF B%<>OldB% THEN
IF B%=4 THEN
REM Mouse just clicked, see if it is for us.
R%=TRUE
FOR I%=0 TO DIM(RB{()},1)
IF ABS(X%-RB{(I%)}.x%)<=20 AND ABS(Y%-RB{(I%)}.y%)<=20 THEN R%=I% : REM Bingo R% is the click target.
NEXT
REM now check the status of R%
IF R% <> TRUE IF RB{(R%)}.state% =0 THEN
PROCalloff(RB{()}) :REM show all off.
RB{(R%)}.state%=1 :REM Set new button state to on.
PROCdraw(RB{()}, R%) :REM Draw that button again.
ENDIF
ENDIF
ENDIF
OldB%=B%
WAIT 5
UNTIL FALSE
END
DEF PROCdraw(a{()}, b%)
LOCAL x%, y%
x%=a{(b%)}.x% y%=a{(b%)}.y%
GCOL 7: CIRCLE FILL x%,y%,20
IF a{(b%)}.state% GCOL0: CIRCLE FILL x%,y%,15
GCOL 7 :MOVE x%+50,y%+10 :PRINT a{(b%)}.text$
ENDPROC
DEF PROCalloff(a{()})
LOCAL x%, y%, I%
REM We switch them all off pending the new selection
FOR I%=0 TO DIM(a{()},1)
x%=a{(I%)}.x% y%=a{(I%)}.y%
GCOL 7: CIRCLE FILL x%,y%,20
a{(I%)}.state%=0
NEXT
ENDPROC
I hope this gives you or others some ideas that you can build on.
UPDATE: I have "improved" this adding the highlighting when there is a mouse over, and separating out the drawing part so that you can easily modify the button shape. It uses more CPU time so I have tried to avoid unnecessary redrawing. Here goes:
Code: Select all
REM Version 2 'improved?'
MODE 8
VDU 5
OFF
REM Define buttons and initial state.
Bsize%=20
DIM RB{(5) x%, y%, state%, text$}
DATA 100,600,1,"One",100,500,0,"Two",100,400,0,"Three",100,300,0,"Four",100,200,0,"Five",100,100,0,"Six"
REM Display buttons
FOR I%=0 TO DIM(RB{()},1)
READ RB{(I%)}.x%, RB{(I%)}.y%, RB{(I%)}.state%, RB{(I%)}.text$
PROCdraw(RB{()},I% ,0, Bsize%)
NEXT
OldProd%=0 : OldB%=0 :Last%=TRUE
REM Check for mouse over button and click
REPEAT
REM Main program loop
MOUSE X%,Y%,B%
Q%=X%*Y%+B% :REM Used to see if mouse is changing at all, if it isn't then there is nothing to do...
IF Q% <> OldProd% THEN
R%=TRUE
FOR I%=0 TO DIM(RB{()},1)
IF ABS(X%-RB{(I%)}.x%)<=Bsize% IF ABS(Y%-RB{(I%)}.y%)<=Bsize% THEN R%=I% : REM R% is the click target.
NEXT
IF R%<>TRUE THEN
REM we are over control R%
IF B%<>OldB% IF B%=4 THEN
REM Button press detected
IF RB{(R%)}.state% =0 THEN
REM We clicked on a button that was off.
PROCalloff(RB{()}, Bsize%) :REM draw all off and reset state flags.
RB{(R%)}.state%=1 :REM Set new button state to on.
ENDIF
ENDIF
PROCdraw(RB{()}, R%, 1, Bsize%) :REM Draw 'mouse over' button in highlight.
Last%=R%
ELSE
IF Last%<>TRUE THEN
REM We are not over a control so redraw the last highlighted button.
PROCdraw(RB{()}, Last%, 0, Bsize%)
Last%=TRUE
ENDIF
ENDIF
OldB%=B%
ENDIF
OldProd%=Q%
WAIT 5
UNTIL FALSE
END
:
DEF PROCdraw(a{()}, b%, n%, s%) :REM b% is the control ID, n% is highlight (1) or normal (0), s% is button Radius
LOCAL x%, y%
x%=a{(b%)}.x% y%=a{(b%)}.y%
IF n% THEN
REM Highlight
GCOL 15: CIRCLE FILL x%,y%,Bsize% :MOVE x%+50,y%+10 :PRINT a{(b%)}.text$
IF a{(b%)}.state% GCOL1: CIRCLE FILL x%,y%,s%*0.75
ELSE
REM Normal
GCOL 7: CIRCLE FILL x%,y%,Bsize% :MOVE x%+50,y%+10 :PRINT a{(b%)}.text$
IF a{(b%)}.state% GCOL0: CIRCLE FILL x%,y%,s%*0.75
ENDIF
ENDPROC
:
DEF PROCalloff(a{()},s%)
LOCAL I%
REM We switch last selection off pending the new selection
FOR I%=0 TO DIM(a{()},1)
IF a{(I%)}.state%=1 a{(I%)}.state%=0 :PROCdraw(a{()}, I%, 0, s%)
NEXT
ENDPROC
Z
Last edited by Zaphod on Mon 09 Jul 2018, 16:44, edited 2 times in total.
Re: Radio Button tool (on/off) (New)
Slider Control
In the same vein here is the toggle switch in the Android Slider guise usually used for settings. Clearly you could make a checkbox graphic using the same logic.
To recap you use this type of control if you only have two options and a radio button if you have 3 or more mutually exclusive options. I have not tried to integrate them but the type of control could be added as an extra structure member and the detection and drawing selected based on an individual control type. You could build up the complete user interface and then use the main loop pretty much as it is here to detect all user input.
Note that I made the origin of the control the mid point to make the code simpler. It is 40 high by 80 wide and hard coded in.
Z
In the same vein here is the toggle switch in the Android Slider guise usually used for settings. Clearly you could make a checkbox graphic using the same logic.
To recap you use this type of control if you only have two options and a radio button if you have 3 or more mutually exclusive options. I have not tried to integrate them but the type of control could be added as an extra structure member and the detection and drawing selected based on an individual control type. You could build up the complete user interface and then use the main loop pretty much as it is here to detect all user input.
Code: Select all
MODE 8
VDU 5
OFF
REM Define buttons and initial state.
DIM Slide{(5) x%, y%, state%, text$}
DATA 100,100,1,"One",100,200,0,"Two",100,300,0,"Three",100,400,1,"Four",100,500,0,"Five",100,600,0,"Six"
REM Display buttons
FOR I%=0 TO DIM(Slide{()},1)
READ Slide{(I%)}.x%, Slide{(I%)}.y%, Slide{(I%)}.state%, Slide{(I%)}.text$
PROCsdraw(Slide{()},I%)
NEXT
MOVE 58,670 :PRINT "Off-On"
REM Check for mouse over button and click
OldB%=0
REPEAT
REM Main program loop
MOUSE X%,Y%,B%
IF B%<>OldB% THEN
IF B%=4 THEN
REM Mouse just clicked, see if it is for us.
R%=TRUE
FOR I%=0 TO DIM(Slide{()},1)
IF ABS(X%-Slide{(I%)}.x%)<=2*20 AND ABS(Y%-Slide{(I%)}.y%)<=20 THEN R%=I% : REM Bingo R% is the click target.
NEXT
REM now check the status of R%
IF R% <> TRUE THEN
REM Change state and text if required.
IF Slide{(R%)}.state% THEN
Slide{(R%)}.state% =0
ELSE
Slide{(R%)}.state% =1 :REM Set new button state.
ENDIF
PROCsdraw(Slide{()}, R%) :REM Draw that button again in new position.
ENDIF
ENDIF
ENDIF
OldB%=B%
WAIT 5
UNTIL FALSE
END
DEF PROCsdraw(a{()}, b%)
LOCAL x%, y%, r%
x%=a{(b%)}.x% y%=a{(b%)}.y% r%=20
GCOL 7: CIRCLE FILL x%-r%,y%,r%
RECTANGLE FILL x%-r%,y%-r%,2*r%
CIRCLE FILL x%+r%,y%,r%
IF a{(b%)}.state% GCOL0: CIRCLE FILL x%+r%,y%,r%-2 ELSE GCOL0: CIRCLE FILL x%-r%,y%,r%-2
GCOL 7 :MOVE x%+50,y%+10 :PRINT a{(b%)}.text$
ENDPROC
Z