I've always hated using if mousex()>xpos type commands to make buttons, so I made a simple way to have buttons with just a bitmap and memblock functions, but even more can be added with a little effort.
Basic Principals and Simple Code.
The basic idea is to load a bitmap, make a memblock from it, and then when the mouse is clicked, get the color of the point where the mouse is, using that to determine which button is being pressed.
Since you don't want your buttons to be solid colors, and you don't want to have to program in hundreds of colors per button, an invisible mapping image is used. It is only loaded long enough for a memblock to be made, and then it's deleted.
In its place, an image with the same button shapes, but much more decoration and detail is shown instead. The coordinates on this image is compared to the coordinates in the memblock.
This is where some functions come into play. Like this one:
function mem_pointr(memNum,x,y)
width = memblock dword(memNum,0)
value = memblock byte(memNum,(y*width*4)+(x*4)+14)
endfunction value
The memNum is the memblock number that the mapping image is stored on, in my examples, it's memblock one.
The x and y are coordinates, usually
mousex() and
mousey().
You will also notice the width variable in the function. The width is always a dword starting at the zero position of the memblock.
Here is a function to grab the width of the memblock:
function mem_width(memNum)
value=memblock dword(memNum,0)
endfunction value
So now, you could write a simple program that fetches the rgb value of a point of the mapping image, and displays it onscreen depending on where you click your mouse.
Advanced Programming and Scripting.
This is more complicated, it includes, or will soon include, how to add effects like an image overlay, and effects and triggers when the mouse hovers over or clicks a button. This includes a scripting method to easily change button images and effects.
The files can be downloaded from the attachment. They include two 200x200 bitmaps, three txt files, and one DBC source file that can be opened in DBC or Notepad. (DBC files have the same format as txt.)
Here's an example program:
remstart
SUMMARY
Buttonmapping demonstration by P Schnell with help from Benjamin.
Uses a bitmap to determine buttons instead of coordinate ranges.
Allows for buttons of any shape and size.
Allows over 16 million buttons to be onscreen at once.
EXPLINATIONS
When using the memblock functions, the display mode must
always be 32-bit, or the functions will be inaccurate.
The memNum variable in the functions should be the
number of the memblock you are using for the buttonmap,
1 in this example.
The x and y variables should be the coordinates of the
pixel to read, usually the mousex() and mousey() coordinates.
CREDITS
Thanks to JessTicular for some help, and Benjamin for
three memblock functions. (Labeled in the functions section.)
remend
`Set display mode and sync rate.
set display mode 640,480,32
sync on
sync rate 100
`Notify user of operation.
print "Reading script file..."
sync
`Read script file.
open to read 1,"script.txt"
`Notify user of operation.
print "Getting map information..."
sync
`Get map name.
do
read string 1,temp$
if lower$(left$(temp$,7))="loadmap" then exit
loop
for char=9 to len(temp$)-1
map$=map$+mid$(temp$,char)
next char
`Notify user of operation.
print "Getting face information..."
sync
`Get face name.
do
read string 1,temp$
if lower$(left$(temp$,8))="loadface" then exit
loop
for char=10 to len(temp$)-1
face$=face$+mid$(temp$,char)
next char
`Notify user of operation.
print "Getting hover information..."
sync
`Get hover name.
do
read string 1,temp$
if lower$(left$(temp$,9))="loadhover" then exit
loop
for char=11 to len(temp$)-1
hover$=hover$+mid$(temp$,char)
next char
`Notify user of operation.
print "Getting down information..."
sync
`Get down name.
do
read string 1,temp$
if lower$(left$(temp$,8))="loaddown" then exit
loop
for char=10 to len(temp$)-1
down$=dwon$+mid$(temp$,char)
next char
`Notify user of operation.
print "Getting button information..."
sync
`Get buttongroup.
do
read string 1,temp$
if lower$(left$(temp$,11))="buttongroup" then exit
loop
for char=13 to len(temp$)-1
elements$=elements$+mid$(temp$,char)
next char
elements=val(elements$)
elementnum=elements
dim elementrgb(elements)
dim element$(elements)
`Get elements.
for elm=1 to elements
read string 1,temp$
char=8
elnum$=""
red$=""
green$=""
blue$=""
name$=""
`Get element number.
do
inc char
if mid$(temp$,char)="," then exit
elnum$=elnum$+mid$(temp$,char)
loop
element=val(elnum$)
`Get element red value.
do
inc char
if mid$(temp$,char)="," then exit
red$=red$+mid$(temp$,char)
loop
red=val(red$)
`Get element green value.
do
inc char
if mid$(temp$,char)="," then exit
green$=green$+mid$(temp$,char)
loop
green=val(green$)
`Get element blue value.
do
inc char
if mid$(temp$,char)="," then exit
blue$=blue$+mid$(temp$,char)
loop
blue=val(blue$)
`Compile element rgb.
elementrgb(element)=rgb(red,green,blue)
`Get element name.
inc char
for char=char to len(temp$)-1
element$(element)=element$(element)+mid$(temp$,char)
next char
`Go to next element.
next elm
`Notify user of operation.
print "Loading images..."
sync
`Load buttonmap.
load bitmap map$,31
make memblock from bitmap 1,31
delete bitmap 31
`Load onscreen image.
load image face$,1
set current bitmap 0
print "Finished. Press any key to continue."
wait key
cls
`Begin main loop.
paste image 1,0,0
set cursor 210,0
print "Click any part of the image."
do
if mouseclick()=1
cls
`Check if the cursor is over the mapping image.
if mousex()<mem_width(1) and mousey()<mem_height(1)
`Tell user the RGB values of the point clicked.
memNum=1:x=mousex():y=mousey()
red=mem_pointr(memNum,x,y)
green=mem_pointg(memNum,x,y)
blue= mem_pointb(memNum,x,y)
set cursor mem_width(memNum)+10,0
if red=0 and green=0 and blue=0
print "No button pressed."
else
for elm=1 to elementnum
if elementrgb(elm)=rgb(red,green,blue)
print element$(elm)," has been pressed."
endif
next elm
endif
else
`Notify user if no button is pressed.
set cursor mem_width(memNum)+10,0
print "No button pressed."
endif
`Only clear screen and repaste if an action has been made.
paste image 1,0,0
endif
`Sync and loop.
sync
loop
`FUNCTIONS
goto endoffunctions
`Finds the width of the mapping image.
function mem_width(memNum)
value=memblock dword(memNum,0)
endfunction value
`Finds the height of the mapping image.
function mem_height(memNum)
value=memblock dword(memNum,4)
endfunction value
`Red Value by Benjamin
`Finds the red value of the selected pixel.
function mem_pointr(memNum,x,y)
width = memblock dword(memNum,0)
value = memblock byte(memNum,(y*width*4)+(x*4)+14)
endfunction value
`Green Value by Benjamin
`Finds the green value of the selected pixel.
function mem_pointg(memNum,x,y)
width = memblock dword(memNum,0)
value = memblock byte(memNum,(y*width*4)+(x*4)+13)
endfunction value
`Blue Value by Benjamin
`Finds the blue value of the selected pixel.
function mem_pointb(memNum,x,y)
width = memblock dword(memNum,0)
value = memblock byte(memNum,(y*width*4)+(x*4)+12)
endfunction value
endoffunctions:
`End
The script for the above program, and the explination of the script format:
LoadMap{map.bmp}
LoadFace{face.bmp}
LoadHover{NULL}
LoadDown{NULL}
Buttongroup(5)
Element{1,255,0,0,One}
Element{2,255,255,0,Two}
Element{3,255,0,255,Three}
Element{4,0,255,255,Four}
Element{5,0,0,255,Five}
EndButtongroup ()
End()
LoadMap{string}
LoadFace{string}
LoadHover{string}
LoadDown{string}
Buttongroup(int)
Element{int,int,int,int,string}
EndButtongroup()
End()
/*
LoadMap{string}
Loads the mapping bitmpap.
string - a string representing the filename of the mapping bitmap. Must be a BMP file.
LoadFace{string}
Loads the face image.
string - a string representing the filename of the face image. Must be a BPM or JPG file.
LoadHover{string}
Loads the hover image.
string - a string representing the filename of the hover image. Must be a BMP or JPG file. If NULL is specified, the face image will also be used as the hover image.
LoadDown{string}
Loads the down image.
string - a string representing the filename of the down image. Must be a BMP or JPG file. If NULL is specified, the face image will also be used as the down image.
Buttongroup(int)
The buttongroup function. The buttongroup may contain upto 16,581,374 elements.
int - An integer between 1 and 16581374. Gives the number of elemets in the buttongroup.
Element{int,int,int,int,string}
Creates a button element.
int - An integer 1 through 16581374. Gives the call number of the button.
int - An integer 0 through 255. Specifies the red value of the button.
int - An integer 0 through 255. Specifies the green value of the button.
int - An integer 0 through 255. Specifies the blue value of the button.
string - A string upto 255 characters long. Specifies the button name.
EndButtongroup()
Ends the buttongroup.
End()
Ends the script.
Notes:
- Integers may not contain decimals or commas.
- Strings may not contain quotation marks.
- Everything is case-sensitive.
- Whitespaces are allowed only in strings.
*/