• Print

Author Topic: Ritchie's QB64 Button Library  (Read 1319 times)

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2264
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Ritchie's QB64 Button Library
« on: June 22, 2011, 01:06:49 PM »
I created a library of functions and procedures to manipulate graphics buttons on screen.  Included in the download below is a full set of documentation and a demo program showing some of the things you can do with the library, like the creation of button arrays.

The functions and procedures are fully contained, requiring no variables to track and are completely non-destructive to the screen.  Any button interaction with the screen will retain the original image underneath the button.

Give it a try and let me know what you think, how it can be improved upon, and most importantly the improvements you made to it.

http://dl.dropbox.com/u/416997/RQBLV10.zip

Clippy

  • Hero Member
  • *****
  • Posts: 16440
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Ritchie's QB64 Button Library
« Reply #1 on: June 22, 2011, 01:29:23 PM »
Very cute! I LOVE those buttons. One thing. The FONT:


font& = _LOADFONT("C:\WINDOWS\Fonts\lucon.ttf", 32, "MONOSPACE")

Might be better to use:

fontpath$ = ENVIRON$("SYSTEMROOT") + "\fonts\lucon.ttf"

Very nice otherwise!

Ted

Maybe include it with the program to make sure...
« Last Edit: June 22, 2011, 01:40:11 PM by Clippy »
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2264
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: Ritchie's QB64 Button Library
« Reply #2 on: June 22, 2011, 01:50:22 PM »
Yes, that would be better to use the font on the user's computer. I should have realized that.

Thanks for the compliment too :)

Clippy

  • Hero Member
  • *****
  • Posts: 16440
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Ritchie's QB64 Button Library
« Reply #3 on: June 22, 2011, 01:56:53 PM »
The way you have it, you could just put a copy of the font in the program folder to make sure.
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

Johny B.

  • Sr. Member
  • ****
  • Posts: 487
    • Email
Re: Ritchie's QB64 Button Library
« Reply #4 on: June 24, 2011, 03:58:31 AM »
Clippy is right. It makes it much easier for us Linux/Mac folks.
John
"Time is an illusion; Lunchtime doubly so." - Douglas Adams

OlDosLover

  • Hero Member
  • *****
  • Posts: 3860
  • OlDosLover
    • Email
Re: Ritchie's QB64 Button Library
« Reply #5 on: June 24, 2011, 04:15:23 AM »
Hi all,
    Very nice library Terrie. Polished and functional. Thanks for shareing.
OlDosLover.

Dav

  • Hero Member
  • *****
  • Posts: 512
Re: Ritchie's QB64 Button Library
« Reply #6 on: June 24, 2011, 06:44:09 PM »
Niiiice!  Well made PDF instructions too.

- Dav
(Visit Dav's Qbasic Site) (Grab my IDE)

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2264
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: Ritchie's QB64 Button Library
« Reply #7 on: June 24, 2011, 09:57:45 PM »
Thanks everyone :)

Had fun making it too. I plan to continue working on it and hopefully some great ideas will come from other users as well.

Clippy

  • Hero Member
  • *****
  • Posts: 16440
  • I LOVE π = 4 * ATN(1)    Use the QB64 WIKI >>>
    • Pete's Qbasic Site
    • Email
Re: Ritchie's QB64 Button Library
« Reply #8 on: June 24, 2011, 11:39:30 PM »
If you ever worked with VB then you know what I would like. A way to create buttons, scroll boxes, text boxes, image boxes, etc. with a kind of drag and drop interface. Your button array reminds me of control arrays too!

The biggest hurdle would be sizing those tools to make a nice looking user interface with all of the mouse coordinates ready to use. It would make game and office programs a snap!

Ted
QB64 WIKI: Main Page
Download Q-Basics Code Demo: Q-Basics.zip
Download QB64 BAT, IconAdder and VBS shortcuts: QB64BAT.zip
Download QB64 DLL files in a ZIP: Program64.zip

unseenmachine

  • Hero Member
  • *****
  • Posts: 3285
  • A fish, a fish, a fishy o!
Re: Ritchie's QB64 Button Library
« Reply #9 on: June 25, 2011, 05:44:10 AM »
More GUI libs is allways a good thing, nice one MR Ritchie.

Here's the button interface from VBQ02. It might come in handy for non-graphics buttons.

Code: [Select]
SCREEN _NEWIMAGE(800, 600, 32)

DIM Button(1) AS Button, Mouse(1) AS MouseInfo

VQB_Button_New Button(0), 15, 15, 100, 24, _RGB(200, 0, 0), _RGB(255, 255, 255), "EXIT", 1
VQB_Button_New Button(1), 400, 300, 100, 24, _RGB(0, 200, 0), _RGB(0, 0, 255), "EXIT", 2

VQB_Button_Draw Button(0)
VQB_Button_Draw Button(1)

DO
    _LIMIT 30
    VQB_Mouse_GetInfo Mouse(0)
    FOR i% = 0 TO 1
        IF VQB_Button_Click(Button(i%), Mouse(0)) THEN
            SELECT CASE i%
                CASE 0 'http:// Exit
                    SYSTEM
                CASE 1 'http:// another exit
                    SYSTEM
            END SELECT
            EXIT FOR
        END IF
    NEXT
LOOP




TYPE Button
    Shape AS INTEGER 'http:// 1=Square, 2=Ellipse
    X AS INTEGER 'http:// Top left if square, Centre if ellipse
    Y AS INTEGER
    Width AS INTEGER 'http:// Used as XRadius! if ellipse
    Height AS INTEGER 'http:// Used as YRadius! if ellipse
    CLR AS LONG
    TextCLR AS LONG
    Text AS STRING * 32
    State AS INTEGER
END TYPE

TYPE MouseInfo
    X AS LONG
    Y AS LONG
    LMB AS INTEGER
    RMB AS INTEGER
END TYPE

SUB VQB_Frame (X%, Y%, Width%, Height%, CLR&)
OldCLR& = CLR&
LINE (X%, Y%)-(X% + Width%, Y% + Height%), CLR&, BF
FOR Border% = 0 TO 4
    IF CLR& > _RGB(0, 0, 0) THEN
        NewRed& = _RED(CLR&) - (6 * Border%)
        NewGreen& = _GREEN(CLR&) - (6 * Border%)
        NewBlue& = _BLUE(CLR&) - (6 * Border%)
        CLR& = _RGB(NewRed&, NewGreen&, NewBlue&)
    ELSE
        NewRed& = _RED(CLR&) + (6 * Border%)
        NewGreen& = _GREEN(CLR&) + (6 * Border%)
        NewBlue& = _BLUE(CLR&) + (6 * Border%)
        CLR& = _RGBA(NewRed&, NewGreen&, NewBlue&, 120)
    END IF
    LINE (X% - Border%, Y% - Border%)-(X% + Width% + Border%, Y% - Border%), CLR&, BF
    LINE (X% - Border%, Y% + Height% + Border%)-(X% + Width% + Border%, Y% + Height% + Border%), CLR&, BF
    LINE (X% - Border%, Y% - Border%)-(X% - Border%, Y% + Height% + Border%), CLR&, BF
    LINE (X% + Width% + Border%, Y% - Border%)-(X% + Width% + Border%, Y% + Height% + Border%), CLR&, BF
NEXT
CLR& = OldCLR&
END SUB


'http:// Buttons

SUB VQB_Button_New (Button AS Button, X%, Y%, Width%, Height%, CLR&, TextClr&, Text$, Shape%)
Button.X = X%
Button.Y = Y%
Button.Width = Width%
Button.Height = Height%
Button.CLR = CLR&
Button.TextCLR = TextClr&
Button.Text = Text$
Button.Shape = Shape%
END SUB


SUB VQB_Button_Draw (Button AS Button)
OldClr& = Button.CLR
IF Button.Shape = 1 THEN 'http:// Square button
    VQB_Frame Button.X, Button.Y, Button.Width, Button.Height, Button.CLR
    COLOR Button.TextCLR, _RGBA(0, 0, 0, 0)
    _PRINTSTRING (Button.X + (Button.Width / 2) - (_PRINTWIDTH(RTRIM$(Button.Text)) / 2), Button.Y + (_FONTHEIGHT / 4)), Button.Text
ELSEIF Button.Shape = 2 THEN 'http:// Ellipse button
    EllipseXS Button.X, Button.Y, Button.Width, Button.Height, 1, Button.CLR, _RGB(7, 7, 7)
    PAINT (Button.X, Button.Y), Button.CLR, Button.CLR
    EllipseXS Button.X, Button.Y, Button.Width, Button.Height, 12, Button.CLR, _RGB(7, 7, 7)
    COLOR Button.TextCLR, _RGBA(0, 0, 0, 0)
    _PRINTSTRING (Button.X - (_PRINTWIDTH(RTRIM$(Button.Text)) / 2), Button.Y - (_FONTHEIGHT / 2)), Button.Text
END IF
Button.CLR = OldClr&
END SUB


FUNCTION VQB_Button_Click (Button AS Button, Mouse AS MouseInfo)
IF Mouse.LMB THEN
    IF Button.Shape = 1 THEN
        IF Mouse.X >= Button.X AND Mouse.X <= Button.X + Button.Width THEN
            IF Mouse.Y >= Button.Y AND Mouse.Y <= Button.Y + Button.Height THEN
                VQB_Button_Click = -1
                IF Button.State THEN Button.State = 0 ELSE Button.State = -1
                EXIT FUNCTION
            END IF
        END IF
    ELSEIF Button.Shape = 2 THEN
        'http:// Ellipse detection adapted from a function created by DarthWho
        'http:// http://www.qb64.net/forum/index.php?topic=3154.15
        Xrad% = Button.Width + 12
        Yrad% = Button.Height + 12
        IF (Mouse.Y - Button.Y) ^ 2 + ((Mouse.X - Button.X) * Yrad% / Xrad%) ^ 2 <= Yrad% * Yrad% THEN
            VQB_Button_Click = -1
            IF Button.State THEN Button.State = 0 ELSE Button.State = -1
            EXIT FUNCTION
        END IF
    END IF
END IF
VQB_ButtonClick = 0
END FUNCTION


'http:// Graphics feature extracted from GDK_Draw 01
SUB EllipseXS (X%, Y%, XRadius!, YRadius!, Wide%, CLR&, ShadeClr&)
FOR j% = 0 TO Wide% - 1
    IF _RED(CLR&) <= 255 AND _RED(ShadeClr&) > 0 THEN newred& = _RED(CLR&) - _RED(ShadeClr&)
    IF _BLUE(CLR&) <= 255 AND _BLUE(ShadeClr&) > 0 THEN newblue& = _BLUE(CLR&) - _BLUE(ShadeClr&)
    IF _GREEN(CLR&) <= 255 AND _GREEN(ShadeClr&) > 0 THEN newgreen& = _GREEN(CLR&) - _GREEN(ShadeClr&)
    CLR& = _RGB(newred&, newgreen&, newblue&)
    IF XRadius! > YRadius! THEN Radius! = XRadius! ELSE Radius! = YRadius!
    MinStep! = 1 / (2 * 3.1415926535 * Radius!) '<<< Thanks to CodeGuy for this optimisation.
    FOR i = 0 TO 8 * ATN(1) STEP MinStep!
        pointx% = X% + (XRadius! * COS(i))
        pointy% = Y% + (YRadius! * SIN(i))
        PSET (pointx%, pointy%), CLR&
    NEXT
    XRadius! = XRadius! + 1
    YRadius! = YRadius! + 1
NEXT
END SUB


'http:// Mouse Input

SUB VQB_Mouse_GetInfo (Mouse AS MouseInfo)
DO
    Mouse.RMB = _MOUSEBUTTON(2)
    Mouse.LMB = _MOUSEBUTTON(1)
    Mouse.X = _MOUSEX
    Mouse.Y = _MOUSEY
LOOP WHILE _MOUSEINPUT
END SUB





UnseenGDK Download : http://dl.dropbox.com/u/8822351/UnseenGDK.bm
GDK Tutorial : http://dl.dropbox.com/u/8822351/UnseenGDK_Tutorial.doc
VQB02 : http://dl.dropbox.com/u/8822351/VQB02.zip

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2264
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: Ritchie's QB64 Button Library
« Reply #10 on: June 25, 2011, 04:33:17 PM »
Clippy, I actually played around with that idea late last year. I had routines for Windows and command buttons (they looked like original win 95), but then Galleon came out with a quick demo of something he was working on in late January. I was blown away by it and figured I would shelve mine thinking his would be coming soon. Does any one know what ever become of his GUI project anyway?

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
Re: Ritchie's QB64 Button Library
« Reply #11 on: July 03, 2011, 06:33:36 AM »
it's interesting that what Clippy has outlined as a "hurdle" is exactly what my CALM library already does, with great gusto.  like Van Damme smashing a brick I'd say.  I will endorse this business after I've gotten a chance to perouse it.  thanks Terry

SMcNeill

  • Hero Member
  • *****
  • Posts: 2414
    • Email
Re: Ritchie's QB64 Button Library
« Reply #12 on: April 16, 2012, 08:01:30 AM »
Nice to see other people's ideas on how o make buttons.  I like the way this one works, and am curious if you'd mind if I used the graphics in some of my own programming sometime?  I always like to get permission before I use someone else's ideals.  :)

Here's the short little routine I use to call up a quick button on the screen:

Code: [Select]
'**********************************************'
'*                                           
'*              Button Routine     
'*                                           
'* Can be used to make a quick, simple looking
'* button (or textbox) appear on the screen   
'* for interaction to be handled later.       
'*                                           
'**********************************************'


SUB button (x1, y1, x2, y2, text$, buttoncolor!, textcolor!, offset)
IF offset < 5 THEN offset = 5
LINE (x1 + 1, y1 + 1)-(x2 - 1, y2 - 1), _RGB(0, 0, 0), B
LINE (x1 + 2, y1 + 2)-(x2 - 2, y2 - 2), _RGB(0, 0, 0), B
LINE (x1 + 3, y1 + 3)-(x2 - 3, y2 - 3), _RGB(0, 0, 0), B
LINE (x1, y1)-(x1 + 3, y1 + 3), _RGB(256, 256, 256)
LINE (x2, y1)-(x2 - 3, y1 + 3), _RGB(256, 256, 256)
LINE (x1, y2)-(x1 + 3, y2 - 3), _RGB(256, 256, 256)
LINE (x2, y2)-(x2 - 3, y2 - 3), _RGB(256, 256, 256)
LINE (x1 + 3, y1 + 3)-(x2 - 3, y2 - 3), buttoncolor!, BF
COLOR textcolor!
_PRINTMODE _KEEPBACKGROUND
_PRINTSTRING (x1 + offset, y1 + offset), text$
_PRINTMODE _FILLBACKGROUND
END SUB


It basically makes a square box, frames it, lets you print a single line in it, and offset the line as needed to center it better for aesthetic purposes.

Just call it up with a simple:
CALL button(428, 200, 852, 530, "", _RGB(0, 0, 0), _RGB(0,0,0), 10)
CALL button(818, 270, 838, 460, "EXIT", _RGB(255,255,0), _RGB(255,0,0), 2)

Since I normally try to run in 1280x720 resolution, the first call would put a black text box with a small white frame on the screen, and then the 2nd call would put an exit button down in the bottom corner of that box. 

It's just a small, simple, button box which doesn't require any graphics or pictures be included, and keeps overall program size small. 
http://bit.ly/TextImage -- Library of QB64 code to manipulate text and images, as a BM library.
http://bit.ly/Color32 -- A set of color CONST for use in 32 bit mode, as a BI library.

http://bit.ly/DataToDrive - A set of routines to quickly and easily get data to and from the disk.  BI and BM files

TerryRitchie

  • Hero Member
  • *****
  • Posts: 2264
  • FORMAT C:\ /Q /U /AUTOTEST (How to repair Win8)
    • Email
Re: Ritchie's QB64 Button Library
« Reply #13 on: April 16, 2012, 12:07:50 PM »
Anyone can use the library as they see fit. :)

Glad to see someone is getting some use from it.

Muffinman

  • Sr. Member
  • ****
  • Posts: 379
Re: Ritchie's QB64 Button Library
« Reply #14 on: April 28, 2012, 10:53:52 AM »
hi Terry.  I made some code to show off the workings of some of these methods.  I realize it's not terribly imaginative but check it out, I also added a way to gray out some buttons

I noticed that the buttonupdating becomes sluggish with a low _limit, like 6 loops/sec.  just not sure if there's a way around that

Code: [Select]
lpath$ = "RQBLV10\"
'$include:'RQBLV10\rqbltop.bas'

SCREEN _NEWIMAGE(800, 600, 32)

_SCREENMOVE _MIDDLE
DIM BUTTONstate(0 TO 15) AS _BYTE
CONST defsize = 75, ISGRAYED = 1, DOGRAY = 2, HOVER = 3

PRINT "DEMO: use left and right clicks on the buttons (ESC ends)": PRINT
PRINT TAB(8); "press a key to start"
SLEEP: foo$ = INKEY$: CLS

b1 = BUTTONNEW("big", defsize, defsize, _RGB(45, 127, 33))
b2 = BUTTONNEW("big", defsize, defsize, _RGB(127, 127, 127))
b3 = BUTTONNEW(lpath$ + "big", defsize, defsize, _RGB(127, 127, 127))

CIRCLE (140 + 2 * 8 + BUTTONWIDTH(b1) + BUTTONWIDTH(b2) + BUTTONWIDTH(b3) / 2, 100 + BUTTONHEIGHT(b3) / 2), BUTTONWIDTH(b3) * .88
CIRCLE (1, 300), 287, _DEFAULTCOLOR, , , 5
CIRCLE (400, 1), 287, _DEFAULTCOLOR, , , .33

LINE (0, 0)-(800, 600): LINE (800, 0)-(0, 600)
LINE (0, 0)-(799, 599), , B

BUTTONTOGGLE b3
toggleok%% = -1: playok%% = -1
rest:
BUTTONPUT 140, 100, b1
BUTTONPUT 140 + 8 + BUTTONWIDTH(b1), 100, b2
BUTTONPUT 140 + 2 * 8 + BUTTONWIDTH(b1) + BUTTONWIDTH(b2), 100, b3

DO:
IF _KEYDOWN(27) THEN SOUND 510, .55 * 18: SLEEP .6: SYSTEM

BUTTONUPDATE
bev = 0

IF BUTTONEVENT(b1) = 1 THEN bev = 1
IF BUTTONEVENT(b1) = 2 THEN bev = 3
IF BUTTONEVENT(b1) = HOVER THEN IF playok%% THEN PLAY "o2 MS L6 N20 p16 L24 N22 N23 p16 N22": playok%% = 0: stopplay& = 60 - 16

IF BUTTONEVENT(b2) = 1 THEN bev = 2
IF BUTTONEVENT(b2) = 2 THEN bev = 4
IF BUTTONEVENT(b2) = HOVER THEN bev = 7

IF BUTTONEVENT(b3) = 1 THEN PLAY "o2 L32 B p32 o1 b"
IF BUTTONEVENT(b3) = 2 THEN IF toggleok%% THEN BUTTONTOGGLE (b3): b3on = b3on XOR -1: bev = 5 - SGN(b3on): toggleok%% = 0: stoptog& = 60 - 5

' grayouts
IF BUTTONstate(b1) = DOGRAY THEN BUTTONstate(b1) = ISGRAYED: ButtonGrayout 140, 100, b1
IF BUTTONstate(b2) = DOGRAY THEN BUTTONstate(b2) = ISGRAYED: ButtonGrayout 140 + 8 + BUTTONWIDTH(b1), 100, b2
IF BUTTONstate(b3) = DOGRAY THEN BUTTONstate(b3) = ISGRAYED: ButtonGrayout 140 + 2 * 8 + BUTTONWIDTH(b1) + BUTTONWIDTH(b2), 100, b3

stoptog& = stoptog& + 1
stopplay& = stopplay& + 1
IF stoptog& MOD 60 = 0 THEN toggleok%% = -1
'IF stopplay& MOD 60 = 0 THEN playok%% = -1
IF bev THEN EXIT DO
_LIMIT 8
LOOP

handlebev: ON bev GOSUB paint1, paint1, paint2, paint3, off3, on3, slowpaint
GOTO rest

p0: RETURN
paint1:
 PAINT (400, 2), _RGB(255, 0, 50), _DEFAULTCOLOR
 IF bev = 1 THEN BUTTONstate(b2) = DOGRAY
 IF bev = 2 THEN BUTTONstate(b1) = DOGRAY
RETURN
paint2:
 PAINT (2, 25), _RGB(70, 210, 20), _DEFAULTCOLOR
RETURN
paint3:
 PAINT (400, 80), _RGBA(180, 180, 180, 15), _DEFAULTCOLOR
RETURN
slowpaint:
 PAINT (400, 2), _RGBA(0, 30, 255, 3), _DEFAULTCOLOR
RETURN
off3:
' replace buttons, ungrayed out; take away yellow paint; and allow green button play
 BUTTONSHOW b1: BUTTONSHOW b2
 BUTTONstate(b1) = 0
 BUTTONstate(b2) = 0
 IF POINT(400, 2) = _RGB(220, 235, 0) THEN PAINT (400, 2), _RGB(0, 0, 0), _DEFAULTCOLOR
 playok%% = -1
RETURN
on3: 'big button -> red
 PAINT (400, 2), _RGB(0, 0, 0), _DEFAULTCOLOR
 PAINT (200, 2), _RGB(0, 0, 0), _DEFAULTCOLOR
 PAINT (400, 80), _RGB(0, 0, 0), _DEFAULTCOLOR
 PAINT (2, 25), _RGB(0, 0, 0), _DEFAULTCOLOR
 PAINT (200, 2), _RGB(220, 235, 0), _DEFAULTCOLOR
 IF BUTTONstate(b1) = ISGRAYED THEN BUTTONstate(b1) = DOGRAY
 IF BUTTONstate(b2) = ISGRAYED THEN BUTTONstate(b2) = DOGRAY
 PLAY "o3 L29 E p32 C p32 E p32 C"
RETURN

SUB ButtonGrayout (bx, by, bidx)
 intensity = 180 ' not too dark, not too light
 DIM i AS INTEGER
 DIM b_image(4 + BUTTONWIDTH(bidx) * BUTTONHEIGHT(bidx)) AS _INTEGER64 ' _UNSIGNED LONG
 temp& = _NEWIMAGE(BUTTONWIDTH(bidx), BUTTONHEIGHT(bidx), 32)
 _SETALPHA 255, 0, temp&
 GET (bx, by)-(bx + BUTTONWIDTH(bidx) - 1, by + BUTTONHEIGHT(bidx) - 1), b_image()
 keeping_dest& = _DEST
 _DEST temp&
 'dither the image
 mask& = _RGBA(intensity, intensity, intensity, 255)
 FOR i = 0 TO BUTTONHEIGHT(bidx) - 1
  SELECT CASE i MOD 2
  CASE 0: LINE (BUTTONWIDTH(bidx), i)-(0, i), mask&, , &H5555
  CASE 1: LINE (BUTTONWIDTH(bidx), i)-(0, i), mask&, , &HAAAA
  END SELECT
 NEXT i
 PUT (0, 0), b_image(), AND
 _DEST keeping_dest&
 BUTTONHIDE bidx
 _PUTIMAGE (bx, by), temp&
 _FREEIMAGE temp&
END SUB

'$include:'RQBLV10\rqbl.bas'

  • Print