TGC Codebase Backup



3D buttons by Coin

2nd Mar 2005 19:01
Summary

Utility which draws clickable '3D-look' buttons on a 2D screen.



Description

Buttons can be drawn in any colour and size, and contain any text. They change colour when the pointer moves over them and give the appearance of being depressed when clicked upon. The programme can optionally branch when buttons are pressed. Although text is automatically centred, the vertical centring control may need adjustment for some fonts or if text containing descenders is used.



Code
                                    ` This code was downloaded from The Game Creators
                                    ` It is reproduced here with full permission
                                    ` http://www.thegamecreators.com
                                    
                                    SET DISPLAY MODE 1024,768,16

CLS RGB(100,100,200)

` Prepare the array which stores all the button information
type ButtonType
  x1 AS INTEGER
  y1 AS INTEGER
  x2 AS INTEGER
  y2 AS INTEGER
  Txt AS STRING
  Font AS STRING
  FontSize AS BYTE
  ThreeD AS BYTE
  ButState AS BYTE
  ButCol AS INTEGER
  CoverCol AS INTEGER
  PressCol AS INTEGER
  TxtCol AS INTEGER
  ThreeDCol AS INTEGER
  HiCol AS INTEGER
  ShadCol AS INTEGER
endtype

NoOfButtons=5
DIM ButtonData(NoOfButtons) AS ButtonType

` At the beginning of the programme define how the buttons will appear
` See the ButtonSetup function for description of the parameters
ButtonSetup(1,50,50,200,75,"NORMAL BUTTON 1","Arial",15,0,RGB(125,125,125),RGB(100,100,100),RGB(80,80,80),RGB(0,0,0),RGB(150,150,150),RGB(255,255,255),RGB(0,0,0))
ButtonSetup(2,50,100,200,125,"NORMAL BUTTON 2","Arial",15,0,RGB(125,125,125),RGB(100,100,100),RGB(80,80,80),RGB(0,0,0),RGB(150,150,150),RGB(255,255,255),RGB(0,0,0))
ButtonSetup(3,50,150,200,175,"EMBOSSED TEXT","Arial",15,1,RGB(125,125,125),RGB(100,100,100),RGB(80,80,80),RGB(0,0,0),RGB(165,165,165),RGB(255,255,255),RGB(0,0,0))
ButtonSetup(4,50,200,200,225,"ETCHED TEXT","Arial",15,2,RGB(125,125,125),RGB(100,100,100),RGB(80,80,80),RGB(0,0,0),RGB(170,170,170),RGB(255,255,255),RGB(0,0,0))
ButtonSetup(5,50,250,200,275,"INACTIVE","Arial",15,0,RGB(125,125,125),RGB(100,100,100),RGB(80,80,80),RGB(0,0,0),RGB(170,170,170),RGB(255,255,255),RGB(0,0,0))

` Display the buttons in their current state
Button(1,2) : rem normal
Button(2,2) : rem normal
Button(3,2) : rem normal
Button(4,2) : rem normal
Button(5,1) : rem inactive; will not respond to clicking

` Describe each button's initial state
for x=1 TO NoOfButtons
  Status(x)
next x

SET CURSOR 50,325
PRINT "Move the pointer over the buttons and click them."
SET CURSOR 50,340
PRINT "Press Esc to quit."

` The main loop which monitors the pointer
do
` Check all buttons in turn
  for But=1 TO NoOfButtons
` Is this button in its normal state?
    if ButtonData(But).ButState=2
` Is the pointer over this button?
      if MOUSEX()>ButtonData(But).x1 AND MOUSEX()<ButtonData(But).x2 AND MOUSEY()>ButtonData(But).y1 AND MOUSEY()<ButtonData(But).y2
` Change the button state to 'covered'
        Button(But,3)
` show its status
        Status(But)
` Loop here until the pointer off the button
        while MOUSEX()>ButtonData(But).x1 AND MOUSEX()<ButtonData(But).x2 AND MOUSEY()>ButtonData(But).y1 AND MOUSEY()<ButtonData(But).y2
` Has the left mouse button been clicked?
          if MOUSECLICK()=1
` Change the button state to 'pressed'
            Button(But,4)
` show its status
            Status(But)

` Enter here your functions/gosubs that control what happens after this button is pressed
` eg. if But=1 then... if But=2 then...

            SLEEP 1000
            EXIT
          endif
        endwhile
` Restore the button state to 'normal'
        Button(But,2)
` show its status
        Status(But)
      endif
    else
` Is this button inactive?
      if ButtonData(But).ButState=1
` show its status
        Status(But)
      endif
    endif
  next But
` Test for key press
  x$=INKEY$()
  if x$<>"" then EXIT
loop

WAIT KEY : END

` Sets up a button for use later
function ButtonSetup(Number,x1,y1,x2,y2,TEXT$,Font$,FontSize,ThreeD,ButCol,CoverCol,PressCol,TxtCol,ThreeDCol,HiCol,ShadCol)
` Number   = number allocated to the button
` x1, y1   = top left coordinates of the button
` x2, y2   = bottom right coordinates of the button
` Text$    = word(s) that appear on the button
` ThreeD   = appearance of Text$:
`              normal if ThreeD=0
`              embossed if ThreeD=1
`              etched if ThreeD=2
` ButCol   = button colour
` CoverCol = button colour when covered by mouse pointer
` PressCol = button colour when pressed
` TextCol  = Text$ colour
` ThreeDCol= ThreeD colour (used with embossing or etching)
` HiCol    = highlight colour (brighter edges of the button)
` ShadCol  = shadow colour (also colour of 'shading' on inactive button)

` set (or reset) and store the button's data
  ButtonData(Number).x1=x1
  ButtonData(Number).y1=y1
  ButtonData(Number).x2=x2
  ButtonData(Number).y2=y2
  ButtonData(Number).Txt=TEXT$
  ButtonData(Number).Font=Font$
  ButtonData(Number).FontSize=FontSize
  ButtonData(Number).ThreeD=ThreeD
  ButtonData(Number).ButState=0 : rem it is unnecessary to pass the ButState parameter during setup since it MUST be 0 anyway
  ButtonData(Number).ButCol=ButCol
  ButtonData(Number).CoverCol=CoverCol
  ButtonData(Number).PressCol=PressCol
  ButtonData(Number).TxtCol=TxtCol
  ButtonData(Number).ThreeDCol=ThreeDCol
  ButtonData(Number).HiCol=HiCol
  ButtonData(Number).ShadCol=ShadCol
endfunction

` Displays a button or changes an existing button's appearance
function Button(Number,NewButState)
` Number   = number allocated to the button
` ButState = appearance of button:
`              not yet drawn if ButState=0
`              inactive if ButState=1
`              normal if ButState=2
`              covered by pointer if ButState=3
`              pressed if ButState=4

` Ensure that the button's new state is different to its existing state
` and that it is due to be drawn
  if ButtonData(Number).ButState<>NewButState AND NewButState>0 AND NewButState<5
` Allocate a colour for the button depending upon its state and draw it
    if NewButState<3 then INK ButtonData(Number).ButCol,0
    if NewButState=3 then INK ButtonData(Number).CoverCol,0
    if NewButState=4 then INK ButtonData(Number).PressCol,0
    BOX ButtonData(Number).x1,ButtonData(Number).y1,ButtonData(Number).x2,ButtonData(Number).y2
` Allocate a colour for its upper and left borders and draw them
    if NewButState=4 then INK ButtonData(Number).ShadCol,0 else INK ButtonData(Number).HiCol,0
    LINE ButtonData(Number).x1,ButtonData(Number).y1,ButtonData(Number).x2-1,ButtonData(Number).y1
    LINE ButtonData(Number).x1,ButtonData(Number).y1,ButtonData(Number).x1,ButtonData(Number).y2-1
` Allocate a colour for its lower and right borders and draw them
    if NewButState=4 then INK ButtonData(Number).HiCol,0 else INK ButtonData(Number).ShadCol,0
    LINE ButtonData(Number).x1,ButtonData(Number).y2,ButtonData(Number).x2,ButtonData(Number).y2
    LINE ButtonData(Number).x2,ButtonData(Number).y1,ButtonData(Number).x2,ButtonData(Number).y2
` Prepare for the text
    SET TEXT TRANSPARENT
    SET TEXT FONT ButtonData(Number).Font
    SET TEXT SIZE ButtonData(Number).FontSize
    FontHeight=ButtonData(Number).FontSize
    Width=TEXT WIDTH(ButtonData(Number).Txt)
` Find the button's horizontal mid point
    MidButtonX=ButtonData(Number).x1+(ButtonData(Number).x2-ButtonData(Number).x1)/2
` Find the button's vertical mid point
    MidButtonY=ButtonData(Number).y1+(ButtonData(Number).y2-ButtonData(Number).y1)/2
` Is the text embossed?
    if ButtonData(Number).ThreeD=1
      INK ButtonData(Number).ThreeDCol,0
` Draw the 3D effect for the text
      TEXT MidButtonX-Width/2-1,MidButtonY-FontHeight/2-1,ButtonData(Number).Txt
    endif
` Is the text etched?
    if ButtonData(Number).ThreeD=2
      INK ButtonData(Number).ThreeDCol,0
` Draw the 3D effect for the text
      TEXT MidButtonX-Width/2+1,MidButtonY-FontHeight/2+1,ButtonData(Number).Txt
    endif
    INK ButtonData(Number).TxtCol,0
` Draw the text to overlap the 3D effect
    TEXT MidButtonX-Width/2,MidButtonY-FontHeight/2,ButtonData(Number).Txt
` Is the button inactive?
    if NewButState=1
      INK ButtonData(Number).ShadCol,0
` Draw the 'shading' over the entire button using separated dots
` Change the step values for heavier or lighter shading
      for y=ButtonData(Number).y1+1 TO ButtonData(Number).y2-1 STEP 2
        for x=ButtonData(Number).x1+1 TO ButtonData(Number).x2-1 STEP 2
          DOT x,y
        next x
      next y
    endif
` Store the button's new state
    ButtonData(Number).ButState=NewButState
  endif
endfunction

function Status(Number)
` Example of what might happen when buttons are covered or pressed (if active)
  if ButtonData(Number).ButState=1 then Status$="inactive "
  if ButtonData(Number).ButState=2 then Status$="normal   "
  if ButtonData(Number).ButState=3 then Status$="covered  "
  if ButtonData(Number).ButState=4 then Status$="pressed  "
  SET CURSOR 250,ButtonData(Number).y1+4
  SET TEXT OPAQUE
  INK RGB(0,0,0),RGB(100,100,200)
  PRINT "Button ";Number;" is ";Status$
endfunction