MSGBOX Library (clone of VBA's MsgBox function)

Post Reply
matt7
Posts: 115
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone
Location: USA

MSGBOX Library (clone of VBA's MsgBox function)

Post by matt7 »

Overview

This library is a built-from-scratch reproduction of VBA's MsgBox function, which is used for displaying messages/prompts to users in Microsoft Office. (See an overview of the VBA version here.)

MSGBOX lets you quickly and easily display a windowed message and 1 to 3 buttons for soliciting a user response to the message. The function returns an enumerated value that lets you determine what button was pressed. You can also choose to display an icon or image to display in the box, and you can customize pretty much anything about the message box's appearance to fit your program's style. Check out the demo script included with the code for lots of examples.

Here is a simple example prompting the user to decide if they want to save before quitting:

Code: Select all

{{/lib/interface/msgbox}}

SET TOOLBAR OFF
GRAPHICS CLEAR
GRAPHICS

text$ = "You have unsaved changes. Would you like to save before quitting?"
response = MSGBOX(text$, MSGBOX.YesNo, MSGBOX.Exclamation)

IF response = MSGBOX.Yes THEN
  ' code to save
END IF
Image

Functions provided:
  • MSGBOX (text$, type, icon)
  • MSGBOX_RESTORE_PARAM_DEFAULTS ()

Inputs and Customization

Required inputs:
  • text$ — This is a string of the message you want to be displayed in the message box. If can include linefeeds using CHR$(10) and can be any length. The text is put into a field, so it is automatically scrollable if the message is very long.
  • type — This is an enumerated value telling the library what type of message box you want (full list below). This determines what buttons are presented to the user for their response.
  • icon — This is an enumerated value telling the library what icon to display in the message box, if any (full list below).
Types:
  • MSGBOX.OkOnly = 0 . . . . . . . . . one button: "Ok"
  • MSGBOX.OkCancel = 1 . . . . . . . . two buttons: "Ok" and "Cancel"
  • MSGBOX.YesNo = 2 . . . . . . . . . . two buttons: "Yes" and "No"
  • MSGBOX.YesNoCancel = 3 . . . . . . three buttons: "Yes", "No", and "Cancel"
  • MSGBOX.RetryCancel = 4 . . . . . . two buttons: "Retry" and "Cancel"
  • MSGBOX.AbortRetryIgnore = 5 . . . three buttons: "Abort", "Retry", and "Ignore"
  • MSGBOX.CustomBttns1 = 6 . . . . . one button: uses parameter MSGBOX.bttn1$
  • MSGBOX.CustomBttns2 = 7 . . . . . two buttons: uses parameters MSGBOX.bttn1$ and .bttn2$
  • MSGBOX.CustomBttns3 = 8 . . . . . three buttons: uses parameters MSGBOX.bttn1$, .bttn2$, and .bttn3$
Icons:
  • MSGBOX.NoIcon = 0 . . . . . . . no icon (text fills the entire message box)
  • MSGBOX.Critical = 1 . . . . . . . red "X" in circle
  • MSGBOX.Exclamation = 2 . . . . yellow "!" in triangle
  • MSGBOX.Question = 3 . . . . . . blue "?" in circle
  • MSGBOX.Information = 4 . . . . blue "i" in circle
  • MSGBOX.CustomImage = 5 . . . uses parameter MSGBOX.iconImagePath$ (path of image file to use)
  • MSGBOX.CustomAscii = 6 . . . . uses parameter MSGBOX.iconAsciiNum (decimal value of unicode character to use)
Return values:
  • MSGBOX.Ok = 0
  • MSGBOX.Cancel = 1
  • MSGBOX.Yes = 2
  • MSGBOX.No = 3
  • MSGBOX.Abort = 4
  • MSGBOX.Retry = 5
  • MSGBOX.Ignore = 6
  • MSGBOX.Button1 = 7 (for custom MSGBOX types)
  • MSGBOX.Button2 = 8 (for custom MSGBOX types)
  • MSGBOX.Button3 = 9 (for custom MSGBOX types)
A quick note about the enumerated inputs (type and icon)... In your MSGBOX function call, you can use either the variable name (for readability) or the hardcoded value (for conciseness). For example:

Code: Select all

' This line of code:
response = MSGBOX("Test", MSGBOX.YesNo, MSGBOX.Question)

' is equivalent to this line of code:
response = MSGBOX("Test", 2, 3)
Other parameters:

In addition to the above inputs, there are many other parameters that can be set before calling the MSGBOX function that controls the appearance of the message box. You can change the color and alpha of anything, including the background behind the message box, and you can also control the duration of the fade-in animation. A list of parameters is given in the "msgbox" file (see the header info at the top of the file), and you can also find many examples in the demo script included with the code.

To give you an example, here are two clean, semi-transparent themes: one light and one dark:

Image

Image


Code

PLEASE READ THE BELOW INFO ON SETTING UP THE LIBRARY!
All code can be found here: https://www.dropbox.com/sh/udk7bhjic863 ... lq_ra?dl=0

IMPORTANT: The location of the msgbox_icons folder must be hardcoded. You must update the variable MSGBOX.dir$ at the top of the "msgbox" file with wherever the library is located. (If anyone knows of a better way to do this, please let me know!)

The MSGBOX library depends on a few other libraries I have written. Those libraries are:
  • graphics_modes — Functions for detecting, setting, saving, and restoring the current graphics mode. (Posted independently here.)
  • draw_fill_settings — Functions for detecting, setting, saving, and restoring the current draw and fill graphics settings. (Inspired by and an adaption of Joel's library)
  • option_sprite_pos — Function for detecting the current OPTION SPRITE POS setting.
  • roundrect — Functions for filling and drawing a rectangle with rounded corners.
For myself, I like keeping these libraries as separate files. I have included all the required files in the Dropbox link above. If you want to also keep all the libraries separate, then you will need to update the library include lines of code at the top of each file based on where you put each file in your folder structure. Or you can replicate how I have my library organized if you don't want to change anything:
  • /lib/
    • graphics/
      • draw_fill_settings
      • graphics_modes
      • roundrect
    • interface/
      • msgbox
      • msgbox_icons/
    • sprites/
      • option_sprite_pos
If you would prefer to just have a single file with all of these libraries combined, then use the below code. (NOTE: You will still need to download the msgbox_icons folder from the Dropbox link above to use the premade icons Critical, Exclamation, Question, and Information.)

Code: Select all

MSGBOX.dir$ = "/lib/interface/"    ' needed for icons

'g'
/*
    MSGBOX (text$, type, icon)
    MSGBOX_RESTORE_PARAM_DEFAULTS ()


Function for displaying a windowed message and 1 to 3 buttons for soliciting a user response.

NOTE: You must update MSGBOX.dir$ above for icons to work.

    Uses: FILL_ROUNDRECT, DRAW_ROUNDRECT,
          SAVE_DRAW_AND_FILL, RESTORE_DRAW_AND_FILL,
          IS_OPTION_SPRITE_POS_CENTRAL

'==============================================================

MSGBOX displays a message, provides buttons for user response, and returns an enumerated value corresponding to the user's response. The required inputs include the text to be displayed, the message box type (which determines the buttons to display), and the icon to be displayed. There are also many parameters that can be set before calling the MSGBOX function for more advanced customization.

  Inputs
  ------

    text$    Text to display in the message box

     type    Message box type (enumerated)

               MSGBOX.OkOnly           = 0
               MSGBOX.OkCancel         = 1
               MSGBOX.YesNo            = 2
               MSGBOX.YesNoCancel      = 3
               MSGBOX.RetryCancel      = 4
               MSGBOX.AbortRetryIgnore = 5
               MSGBOX.CustomBttns1     = 6  (one button)
               MSGBOX.CustomBttns2     = 7  (two buttons)
               MSGBOX.CustomBttns3     = 8  (three buttons)

               For custom types, see the parameter info below

     icon    Icon to display next to the text (enumerated)

               MSGBOX.NoIcon      = 0
               MSGBOX.Critical    = 1
               MSGBOX.Exclamation = 2
               MSGBOX.Question    = 3
               MSGBOX.Information = 4
               MSGBOX.CustomImage = 5
               MSGBOX.CustomAscii = 6

               For custom icons, see the parameter info below

  Output
  ------

    MSGBOX returns an enumerated value corresponding to the button hit by the user. Therefore, the possible return values are dependent on the message box type:

      Responses for type MSGBOX.OkOnly:

        MSGBOX.Ok = 0

      Responses for type MSGBOX.OKCancel:

        MSGBOX.Ok     = 0
        MSGBOX.Cancel = 1

      Responses for type MSGBOX.YesNo:

        MSGBOX.Yes = 2
        MSGBOX.No  = 3

      Responses for type MSGBOX.YesNoCancel:

        MSGBOX.Yes    = 2
        MSGBOX.No     = 3
        MSGBOX.Cancel = 1

      Responses for type MSGBOX.RetryCancel:

        MSGBOX.Retry  = 5
        MSGBOX.Cancel = 1

      Responses for type MSGBOX.AbortRetryIgnore:

        MSGBOX.Abort  = 4
        MSGBOX.Retry  = 5
        MSGBOX.Ignore = 6

      Responses for type MSGBOX.Custom1:

        MSGBOX.Button1 = 7

      Responses for type MSGBOX.Custom2:

        MSGBOX.Button1 = 7
        MSGBOX.Button2 = 8

      Responses for type MSGBOX.Custom3:

        MSGBOX.Button1 = 7
        MSGBOX.Button2 = 8
        MSGBOX.Button3 = 9

  Parameters
  ----------

    NOTE: The option SET BUTTONS CUSTOM can be used in conjunction with FILL COLOR, FILL ALPHA, DRAW COLOR, and DRAW ALPHA for controlling the appearance of the buttons in the message box. This will not interfere with the below parameters that set color and alpha values for other elements of the message box. The options SET BUTTONS FONT NAME and SET BUTTONS FONT SIZE can also be used as they would normally.

    Fade-in animation:
    ------------------

    MSGBOX.fadeDuration sets the length of time in seconds of the message box's fade-in animation. Set to 0 to disable the fade-in animation.


    Message box background:
    -----------------------

    MSGBOX.bgR, .bgG, .bgB, and .bgA set the background color and alpha that appears behind the message box.


    Message box and text:
    ---------------------

    MSGBOX.boxFillR, .boxFillG, .boxFillB, and .boxFillA set the fill color and alpha of the message box.

    MSGBOX.boxOutlineR, .boxOutlineG, .boxOutlineB, and .boxOutlineA set the color and alpha of the message box's outline.

    MSGBOX.txtR, .txtG, .txtB, and .txtA set the color and alpha of the message box's text.

    MSGBOX.txtFont$ sets the font name to use for the message box's text. Set to "default" to use the default field font.

    MSGBOX.txtSize sets the font size to use for the message box's text. Set to -1 to use the default field font size.


    Message box icon and buttons:
    -----------------------------

    MSGBOX.iconImagePath$ specifies the image file to use as the message box's icon when the input "icon" is set to MSGBOX.CustomImage.

    MSGBOX.iconAsciiNum specifies the Unicode character to use as the message box's icon when the input "icon" is set to MSGBOX.CustomAscii.

    MSGBOX.iconR, .iconG, .iconB, and .iconA set the color of alpha of the message box's icon. The RGB values only apply to ASCII icons. The alpha value applies to all icons.

    MSGBOX.bttn1$, .bttn2$, and .bttn3$ set the text to use in the user response buttons when the input "type" is set to MSGBOX.CustomBttns1 (one button), MSGBOX.CustomBttns2 (two buttons), or MSGBOX.CustomBttns3 (three buttons).

'==============================================================

MSGBOX_RESTORE_PARAM_DEFAULTS returns all parameters to their initial values.

'==============================================================
*/
''
'b'
'==============================================================
'  Initialization
'==============================================================

''
'  Types (enumerated)
' ----------------------

MSGBOX.OkOnly = 0
MSGBOX.OkCancel = 1
MSGBOX.YesNo = 2
MSGBOX.YesNoCancel = 3
MSGBOX.RetryCancel = 4
MSGBOX.AbortRetryIgnore = 5
MSGBOX.CustomBttns1 = 6
MSGBOX.CustomBttns2 = 7
MSGBOX.CustomBttns3 = 8
MSGBOX.NUM_TYPES = 9

DIM MSGBOX.numButtons(MSGBOX.NUM_TYPES)
MSGBOX.numButtons(MSGBOX.OkOnly) = 1
MSGBOX.numButtons(MSGBOX.OkCancel) = 2
MSGBOX.numButtons(MSGBOX.YesNo) = 2
MSGBOX.numButtons(MSGBOX.YesNoCancel) = 3
MSGBOX.numButtons(MSGBOX.RetryCancel) = 2
MSGBOX.numButtons(MSGBOX.AbortRetryIgnore) = 3
MSGBOX.numButtons(MSGBOX.CustomBttns1) = 1
MSGBOX.numButtons(MSGBOX.CustomBttns2) = 2
MSGBOX.numButtons(MSGBOX.CustomBttns3) = 3


'  Icons (enumerated)
' --------------------

MSGBOX.NoIcon = 0
MSGBOX.Critical = 1
MSGBOX.Exclamation = 2
MSGBOX.Question = 3
MSGBOX.Information = 4
MSGBOX.CustomImage = 5
MSGBOX.CustomAscii = 6


'  Responses (enumerated)
' ------------------------

MSGBOX.Ok = 0
MSGBOX.Cancel = 1
MSGBOX.Yes = 2
MSGBOX.No = 3
MSGBOX.Abort = 4
MSGBOX.Retry = 5
MSGBOX.Ignore = 6
MSGBOX.Button1 = 7    ' for custom types
MSGBOX.Button2 = 8
MSGBOX.Button3 = 9


'  Default Parameter Values
' --------------------------

MSGBOX_RESTORE_PARAM_DEFAULTS()


DEF MSGBOX_RESTORE_PARAM_DEFAULTS ()

  MSGBOX.fadeDuration = 0.2

  MSGBOX.bgR = 0
  MSGBOX.bgG = 0
  MSGBOX.bgB = 0
  MSGBOX.bgA = 0.2

  MSGBOX.boxFillR = 0.9
  MSGBOX.boxFillG = 0.9
  MSGBOX.boxFillB = 0.9
  MSGBOX.boxFillA = 1

  MSGBOX.boxOutlineR = 0
  MSGBOX.boxOutlineG = 0
  MSGBOX.boxOutlineB = 0
  MSGBOX.boxOutlineA = 1

  MSGBOX.txtR = 0
  MSGBOX.txtG = 0
  MSGBOX.txtB = 0
  MSGBOX.txtA = 1
  MSGBOX.txtFont$ = "default"
  MSGBOX.txtSize = -1            ' set to -1 for default

  MSGBOX.iconR = 0
  MSGBOX.iconG = 0
  MSGBOX.iconB = 0
  MSGBOX.iconA = 1

  MSGBOX.bttn1$ = "1"
  MSGBOX.bttn2$ = "2"
  MSGBOX.bttn3$ = "3"

END DEF

'b'
'==============================================================
'  Main Function
'==============================================================

''
DEF MSGBOX (text$, type, icon)

'  Setup
' -------

  GET SCREEN SIZE scrW, scrH

  GET_DRAW_AND_FILL()          ' Also stores the graphics mode
  dr = GET_DRAW_AND_FILL.dr
  dg = GET_DRAW_AND_FILL.dg
  db = GET_DRAW_AND_FILL.db
  da = GET_DRAW_AND_FILL.da
  fr = GET_DRAW_AND_FILL.fr
  fg = GET_DRAW_AND_FILL.fg
  fb = GET_DRAW_AND_FILL.fb
  fa = GET_DRAW_AND_FILL.fa
  fs = GET_DRAW_AND_FILL.fs
  tp = GET_DRAW_AND_FILL.tpCentral
  gm$ = GET_DRAW_AND_FILL.gm$
  GRAPHICS MODE NORMAL

  sp = IS_OPTION_SPRITE_POS_CENTRAL()
  OPTION SPRITE POS NORMAL

  nPg$ = "msgbox_page"
  nBox$ = "msgbox_box"
  nIco$ = "msgbox_icon"
  nTxt$ = "msgbox_text"
  nBn1$ = "msgbox_bttn_1"
  nBn2$ = "msgbox_bttn_2"
  nBn3$ = "msgbox_bttn_3"


'  Page
' ------

  PAGE nPg$ SET
  PAGE nPg$ FRAME 0, 0, scrW, scrH
  PAGE nPg$ COLOR 0, 0, 0, 0
  PAGE nPg$ ALPHA 0
  PAGE nPg$ SHOW


'  Background and Box Sprite
' ---------------------------

  wBox = INT(scrW*0.8)
  hBox = INT(scrH*0.7)
  IF wBox*0.75 < hBox THEN
    hBox = INT(wBox*0.7)
  ELSE
    wBox = INT(hBox*1.6)
  END IF

  crBox = INT(MIN(wBox, hBox)*0.1)

  mX = INT((scrW - wBox)/2)
  mY = INT((scrH - hBox)/2)

  SPRITE nBox$ BEGIN scrW, scrH
    GRAPHICS CLEAR bgR, bgG, bgB, bgA
    GRAPHICS MODE COPY
    FILL COLOR boxFillR, boxFillG, boxFillB
    FILL ALPHA boxFillA
    FILL_ROUNDRECT(mX, mY, mX+wBox, mY+hBox, crBox)
    DRAW COLOR boxOutlineR, boxOutlineG, boxOutlineB
    DRAW ALPHA boxOutlineA
    DRAW_ROUNDRECT(mX, mY, mX+wBox, mY+hBox, crBox)
  SPRITE END
  SPRITE nBox$ SHOW

  GRAPHICS MODE NORMAL

  margin = INT(hBox*0.1)    ' controls spacing of box elements


'  Icon
' ------

  m = 0

  IF icon = Critical THEN
    SPRITE nIco$ LOAD dir$ & "/msgbox_icons/critical.png"
  ELSE ! IF icon = Exclamation THEN
    SPRITE nIco$ LOAD dir$ & "/msgbox_icons/exclamation.png"
  ELSE ! IF icon = Question THEN
    SPRITE nIco$ LOAD dir$ & "/msgbox_icons/question.png"
  ELSE ! IF icon = Information THEN
    SPRITE nIco$ LOAD dir$ & "/msgbox_icons/information.png"
  ELSE ! IF icon = CustomImage THEN
    IF FILE_EXISTS(iconImagePath$) THEN
      SPRITE nIco$ LOAD iconImagePath$
    ELSE
      icon = NoIcon
    END IF
  ELSE ! IF icon = CustomAscii THEN
    IF iconAsciiNum >= 0 AND iconAsciiNum <= 65535 THEN
      m = 5
      wIco = hBox*0.2
      hIco = hBox*0.2
      SPRITE nIco$ BEGIN wIco+2*m, hIco+2*m
        OPTION TEXT POS CENTRAL
        DRAW COLOR iconR, iconG, iconB
        DRAW ALPHA 1
        DRAW FONT SIZE hIco
        DRAW TEXT CHR$(iconAsciiNum) AT m+wIco/2, m+hIco/2
      SPRITE END
    ELSE
      icon = NoIcon
    END IF
  ELSE
    icon = NoIcon
  END IF ! END IF ! END IF ! END IF ! END IF ! END IF

  IF icon <> NoIcon THEN
    GET SPRITE nIco$ SIZE wIco, hIco
    scIco = hBox*0.2/wIco

    xIco = mX + margin - (wIco/2 - margin)
    yIco = mY + margin - (hIco/2 - margin)

    SPRITE nIco$ AT xIco, yIco SCALE scIco
    SPRITE nIco$ ALPHA iconA
    SPRITE nIco$ SHOW
  END IF


'  Buttons
' ---------

  SET_DRAW(dr, dg, db, da)    ' Support SET BUTTONS CUSTOM
  SET_FILL(fr, fg, fb, fa)
  DRAW FONT SIZE fs

  IF type < 0 OR type >= NUM_TYPES THEN type = OkOnly

  hBn = hBox*0.2
  yBn = (scrH+hBox)/2 - hBn - margin/2

  IF numButtons(type) = 1 THEN
    wBn = wBox/2
    xBn1 = scrW/2 - wBn/2

    IF type = OkOnly THEN tBn1$ = "Ok"
    IF type = CustomBttns1 THEN tBn1$ = bttn1$

    BUTTON nBn1$ TEXT tBn1$ AT xBn1, yBn SIZE wBn, hBn

  ELSE ! IF numButtons(type) = 2 THEN
    wBn = wBox*0.42
    xBn1 = scrW/2 - wBn/2 - wBn/2 - margin/6
    xBn2 = scrW/2 - wBn/2 + wBn/2 + margin/6

    IF type = OkCancel THEN
      tBn1$ = "Ok"
      tBn2$ = "Cancel"
    END IF
    IF type = YesNo THEN
      tBn1$ = "Yes"
      tBn2$ = "No"
    END IF
    IF type = RetryCancel THEN
      tBn1$ = "Retry"
      tBn2$ = "Cancel"
    END IF
    IF type = CustomBttns2 THEN
      tBn1$ = bttn1$
      tBn2$ = bttn2$
    END IF

    BUTTON nBn1$ TEXT tBn1$ AT xBn1, yBn SIZE wBn, hBn
    BUTTON nBn2$ TEXT tBn2$ AT xBn2, yBn SIZE wBn, hBn

  ELSE ' numButtons(type) = 3
    wBn = wBox*0.3
    xBn1 = scrW/2 - wBn/2 - wBn - margin/6
    xBn2 = scrW/2 - wBn/2
    xBn3 = scrW/2 - wBn/2 + wBn + margin/6

    IF type = YesNoCancel THEN
      tBn1$ = "Yes"
      tBn2$ = "No"
      tBn3$ = "Cancel"
    END IF
    IF type = AbortRetryIgnore THEN
      tBn1$ = "Abort"
      tBn2$ = "Retry"
      tBn3$ = "Ignore"
    END IF
    IF type = CustomBttns3 THEN
      tBn1$ = bttn1$
      tBn2$ = bttn2$
      tBn3$ = bttn3$
    END IF

    BUTTON nBn1$ TEXT tBn1$ AT xBn1, yBn SIZE wBn, hBn
    BUTTON nBn2$ TEXT tBn2$ AT xBn2, yBn SIZE wBn, hBn
    BUTTON nBn3$ TEXT tBn3$ AT xBn3, yBn SIZE wBn, hBn

  END IF ! END IF


'  Text Field
' ------------

  mAdj = margin/4    ' counteracts field padding

  IF icon <> NoIcon THEN
    wTxt = wBox - 3*margin - scIco*wIco + 2*mAdj
    xTxt = mX + 2*margin + scIco*wIco - mAdj
    yTxt = mY + margin - 2*mAdj
  ELSE
    wTxt = wBox - 2*margin + 2*mAdj
    xTxt = (scrW-wBox)/2 + margin - mAdj
    yTxt = (scrH-hBox)/2 + margin - 2*mAdj
  END IF

  hTxt = hBox - 1.5*margin - hBn

  FIELD nTxt$ TEXT text$ AT xTxt, yTxt SIZE wTxt, hTxt RO ML
  FIELD nTxt$ BACK ALPHA 0
  FIELD nTxt$ FONT COLOR txtR, txtG, txtB
  FIELD nTxt$ FONT ALPHA txtA
  IF txtFont$ <> "default" THEN
    FIELD nTxt$ FONT NAME txtFont$
  END IF
  IF txtSize > -1 THEN
    FIELD nTxt$ FONT SIZE txtSize
  END IF
  FIELD nTxt$ SELECT 0, 0    ' Scroll to top in case text is long


'  Show message box
' ------------------

  IF fadeDuration > 0 THEN
    tFadeStart = TIME()
    tFadeCurr = tFadeStart
    tFadeEnd = tFadeStart + fadeDuration

    WHILE tFadeCurr <= tFadeEnd
      tFadeCurr = TIME()
      v = (tFadeCurr - tFadeStart)/fadeDuration
      PAGE nPg$ ALPHA v
    END WHILE
  END IF

  PAGE nPg$ ALPHA 1

  ' Ignore any button pressed up until this point
  z = BUTTON_PRESSED(nBn1$)
  IF numButtons(type) > 1 THEN z = BUTTON_PRESSED(nBn2$)
  IF numButtons(type) > 2 THEN z = BUTTON_PRESSED(nBn3$)


'  Get User Response
' -------------------

  response = -1

  DO

    SLOWDOWN

    IF numButtons(type) = 1 THEN
      IF BUTTON_PRESSED(nBn1$) THEN
        IF type = OkOnly       THEN response = Ok
        IF type = CustomBttns1 THEN response = Button1
      END IF

    ELSE ! IF numButtons(type) = 2 THEN
      IF BUTTON_PRESSED(nBn1$) THEN
        IF type = OkCancel     THEN response = Ok
        IF type = YesNo        THEN response = Yes
        IF type = RetryCancel  THEN response = Retry
        IF type = CustomBttns2 THEN response = Button1
      END IF
      IF BUTTON_PRESSED(nBn2$) THEN
        IF type = OkCancel     THEN response = Cancel
        IF type = YesNo        THEN response = No
        IF type = RetryCancel  THEN response = Cancel
        IF type = CustomBttns2 THEN response = Button2
      END IF

    ELSE ' numButtons(type) = 3 THEN
      IF BUTTON_PRESSED(nBn1$) THEN
        IF type = YesNoCancel      THEN response = Yes
        IF type = AbortRetryIgnore THEN response = Abort
        IF type = CustomBttns3     THEN response = Button1
      END IF
      IF BUTTON_PRESSED(nBn2$) THEN
        IF type = YesNoCancel      THEN response = No
        IF type = AbortRetryIgnore THEN response = Retry
        IF type = CustomBttns3     THEN response = Button2
      END IF
      IF BUTTON_PRESSED(nBn3$) THEN
        IF type = YesNoCancel      THEN response = Cancel
        IF type = AbortRetryIgnore THEN response = Ignore
        IF type = CustomBttns3     THEN response = Button3
      END IF

    END IF ! END IF

  UNTIL response > -1


'  Cleanup
' ---------

  SPRITE nBox$ DELETE
  FIELD nTxt$ DELETE
  BUTTON nBn1$ DELETE
  IF numButtons(type) > 1 THEN BUTTON nBn2$ DELETE
  IF numButtons(type) > 2 THEN BUTTON nBn3$ DELETE
  IF icon <> NoIcon THEN SPRITE nIco$ DELETE
  PAGE nPg$ HIDE

  SET_GRAPHICS_MODE(gm$)
  IF tp = 0 THEN
    OPTION TEXT POS NORMAL
  ELSE
    OPTION TEXT POS CENTRAL
  END IF
  IF sp = 0 THEN
    OPTION SPRITE POS NORMAL
  ELSE
    OPTION SPRITE POS CENTRAL
  END IF
  

  RETURN response

END DEF

'==============================================================

'g'
/*
    GET_GRAPHICS_MODE$ ()
    SET_GRAPHICS_MODE (gm$)


Functions for detecting and setting the graphics mode.

Note: GET_GRAPHICS_MODE$ cannot be called while editing a sprite's graphics layer.

'==============================================================

GET_GRAPHICS_MODE$ detects the current graphics mode and returns it as a string (e.g. "NORMAL", "MULTIPLY", "SCREEN", etc.).

'==============================================================

SET_GRAPHICS_MODE sets the graphics mode based on the input.

  Inputs
  ------

    gm$    Graphics mode string (e.g. "MULTIPLY")

'==============================================================
*/
''
DEF GET_GRAPHICS_MODE$ ()

  r1 = 0.7  !  r2 = 0.1
  g1 = 0.0  !  g2 = 0.3
  b1 = 1.0  !  b2 = 0.7
  a1 = 0.2  !  a2 = 0.9

  nScan$ = "save_graphics_mode_screen"
  SPRITE nScan$ SCAN 0, 0, 2, 2

  DRAW PIXEL 0, 0 COLOR r1, g1, b1, a1

  nStamp$ = "save_graphics_mode_stamp"
  SPRITE nStamp$ BEGIN 1, 1
    GRAPHICS CLEAR r2, g2, b2, a2
  SPRITE END

  SPRITE nStamp$ STAMP
  GET PIXEL 0, 0 COLOR r, g, b, a

  r$ = INT(r*255)
  g$ = INT(g*255)
  b$ = INT(b*255)
  a$ = INT(a*255)
  c$ = r$ & "-" & g$ & "-" & b$ & "-" & a$

  IF c$ = "28-75-180-235" THEN gm$ = "NORMAL"
  IF c$ = "26-60-180-235" THEN gm$ = "MULTIPLY"
  IF c$ = "59-75-194-235" THEN gm$ = "SCREEN"
  IF c$ = "44-60-194-235" THEN gm$ = "OVERLAY"
  IF c$ = "28-60-180-235" THEN gm$ = "DARKEN"
  IF c$ = "58-75-194-235" THEN gm$ = "LIGHTEN"
  IF c$ = "61-60-255-235" THEN gm$ = "COLORDODGE"
  IF c$ = "0-0-194-235"   THEN gm$ = "COLORBURN"
  IF c$ = "49-60-194-235" THEN gm$ = "SOFTLIGHT"
  IF c$ = "30-60-194-235" THEN gm$ = "HARDLIGHT"
  IF c$ = "52-75-160-235" THEN gm$ = "DIFFERENCE"
  IF c$ = "55-75-160-235" THEN gm$ = "EXCLUSION"
  IF c$ = "23-76-194-235" THEN gm$ = "HUE"
  IF c$ = "50-66-181-235" THEN gm$ = "SATURATION"
  IF c$ = "29-76-181-235" THEN gm$ = "COLOR"
  IF c$ = "52-60-187-235" THEN gm$ = "LUMINOSITY"
  IF c$ = "0-0-0-0"       THEN gm$ = "CLEAR"
  IF c$ = "26-77-179-230" THEN gm$ = "COPY"
  IF c$ = "28-78-183-46"  THEN gm$ = "SOURCEIN"
  IF c$ = "26-78-179-184" THEN gm$ = "SOURCEOUT"
  IF c$ = "40-65-185-51"  THEN gm$ = "SOURCEATOP"
  IF c$ = "58-60-194-235" THEN gm$ = "DESTOVER"
  IF c$ = "177-0-255-46"  THEN gm$ = "DESTIN"
  IF c$ = "204-0-255-5"   THEN gm$ = "DESTOUT"
  IF c$ = "54-61-193-230" THEN gm$ = "DESTATOP"
  IF c$ = "28-74-179-189" THEN gm$ = "XOR"
  IF c$ = "32-43-186-255" THEN gm$ = "PLUSDARKER"
  IF c$ = "58-69-212-255" THEN gm$ = "PLUSLIGHTER"

  GRAPHICS MODE COPY
  SPRITE nScan$ STAMP
  SET_GRAPHICS_MODE(gm$)

  RETURN gm$

END DEF

'==============================================================

DEF SET_GRAPHICS_MODE (gm$)

  gm$ = CAPSTR$(gm$)

  IF gm$ = "NORMAL"      THEN GRAPHICS MODE NORMAL
  IF gm$ = "MULTIPLY"    THEN GRAPHICS MODE MULTIPLY
  IF gm$ = "SCREEN"      THEN GRAPHICS MODE SCREEN
  IF gm$ = "OVERLAY"     THEN GRAPHICS MODE OVERLAY
  IF gm$ = "DARKEN"      THEN GRAPHICS MODE DARKEN
  IF gm$ = "LIGHTEN"     THEN GRAPHICS MODE LIGHTEN
  IF gm$ = "COLORDODGE"  THEN GRAPHICS MODE COLORDODGE
  IF gm$ = "COLORBURN"   THEN GRAPHICS MODE COLORBURN
  IF gm$ = "SOFTLIGHT"   THEN GRAPHICS MODE SOFTLIGHT
  IF gm$ = "HARDLIGHT"   THEN GRAPHICS MODE HARDLIGHT
  IF gm$ = "DIFFERENCE"  THEN GRAPHICS MODE DIFFERENCE
  IF gm$ = "EXCLUSION"   THEN GRAPHICS MODE EXCLUSION
  IF gm$ = "HUE"         THEN GRAPHICS MODE HUE
  IF gm$ = "SATURATION"  THEN GRAPHICS MODE SATURATION
  IF gm$ = "COLOR"       THEN GRAPHICS MODE COLOR
  IF gm$ = "LUMINOSITY"  THEN GRAPHICS MODE LUMINOSITY
  IF gm$ = "CLEAR"       THEN GRAPHICS MODE CLEAR
  IF gm$ = "COPY"        THEN GRAPHICS MODE COPY
  IF gm$ = "SOURCEIN"    THEN GRAPHICS MODE SOURCEIN
  IF gm$ = "SOURCEOUT"   THEN GRAPHICS MODE SOURCEOUT
  IF gm$ = "SOURCEATOP"  THEN GRAPHICS MODE SOURCEATOP
  IF gm$ = "DESTOVER"    THEN GRAPHICS MODE DESTOVER
  IF gm$ = "DESTIN"      THEN GRAPHICS MODE DESTIN
  IF gm$ = "DESTOUT"     THEN GRAPHICS MODE DESTOUT
  IF gm$ = "DESTATOP"    THEN GRAPHICS MODE DESTATOP
  IF gm$ = "XOR"         THEN GRAPHICS MODE XOR
  IF gm$ = "PLUSDARKER"  THEN GRAPHICS MODE PLUSDARKER
  IF gm$ = "PLUSLIGHTER" THEN GRAPHICS MODE PLUSLIGHTER

END DEF

'==============================================================

'g'
/*
    GET_DRAW_AND_FILL ()
    SET_DRAW (r, g, b, a)
    SET_FILL (r, g, b, a)


Functions for detecting and setting the current draw and fill settings.

Note: GET_DRAW_AND_FILL cannot be called while editing a sprite's graphics layer.

Inspired by and an adaption of Joel's library file for saving and restoring graphics parameters (https://kibernetik.pro/forum/viewtopic.php?f=70&t=1730#p10857)

    Uses: GET_GRAPHICS_MODE$, SET_GRAPHICS_MODE

'==============================================================

GET_DRAW_AND_FILL detects the following graphics settings:

    DRAW COLOR
    DRAW ALPHA

    FILL COLOR
    FILL ALPHA

    DRAW SIZE
    DRAW FONT SIZE
    OPTION TEXT POS

The values of the detected settings can be retrieved from these variables after calling the function:

    GET_DRAW_AND_FILL.dr    Draw color (red)
    GET_DRAW_AND_FILL.dg    Draw color (green)
    GET_DRAW_AND_FILL.db    Draw color (blue)
    GET_DRAW_AND_FILL.da    Draw alpha

    GET_DRAW_AND_FILL.fr    Fill color (red)
    GET_DRAW_AND_FILL.fg    Fill color (green)
    GET_DRAW_AND_FILL.fb    Fill color (blue)
    GET_DRAW_AND_FILL.fa    Fill alpha

    GET_DRAW_AND_FILL.ds    Draw size
    GET_DRAW_AND_FILL.fs    Draw font size

    GET_DRAW_AND_FILL.tpCentral    Text pos central (boolean)
    GET_DRAW_AND_FILL.tpNormal     Text pos normal (boolean)

NOTE: There is a bug that causes the DRAW LINECAP option (possible values "RECT" and "ROUND") to always be reset to RECT when a SPRITE BEGIN command is called. This means that the DRAW LINECAP option cannot be detected without making certain assumptions about graphics settings. The SPRITE BEGIN command is unavoidable: If draw settings are tested and detected inside a sprite graphics layer (the current method employed), then obviously a SPRITE BEGIN command is necessary. If draw settings are tested and detected inside the main graphics layer after a SPRITE SCAN command, the option is still reset during the call to GET_GRAPHICS_MODE$ since a SPRITE BEGIN command is necessary for detecting the graphics mode.

'==============================================================

SET_DRAW sets the draw RGBA settings based on the inputs.

  Inputs
  ------

    r    Draw color (red)
    g    Draw color (green)
    b    Draw color (blue)
    a    Draw alpha

'==============================================================

SET_FILL sets the fill RGBA settings based on the inputs.

  Inputs
  ------

    r    Fill color (red)
    g    Fill color (green)
    b    Fill color (blue)
    a    Fill alpha

'==============================================================
*/
''
DEF GET_DRAW_AND_FILL ()

  scrH = SCREEN_HEIGHT()
  gm$ = GET_GRAPHICS_MODE$()

  n$ = "save_draw_and_fill_settings"
  SPRITE n$ BEGIN 2, scrH
    GRAPHICS MODE COPY
    box$ = CHR$(9608)    ' box$ = "█"

    ' Draw font size
    fs = FONT_SIZE()

    ' Draw color and alpha
    DRAW FONT SIZE 20                  ' Doesn't depend on
    DRAW TEXT box$ AT -1, -1           ' DRAW SIZE setting
    GET PIXEL 1, 1 COLOR dr,dg,db,da
    IF da < 1 THEN                     ' GET PIXEL is not 100%
      DRAW ALPHA 1                     ' accurate for alpha
      DRAW TEXT box$ AT -1, -1         ' values less than 1
      GET PIXEL 1, 1 COLOR dr,dg,db
    END IF

    ' Text position option
    GRAPHICS CLEAR
    DRAW ALPHA 1
    DRAW TEXT box$ AT 5, 5
    GET PIXEL 0, 0 COLOR v, v, v, v
    IF v THEN tpCentral = 1 ELSE tpCentral = 0
    tpNormal = 1 - tpCentral

    ' Draw size
    GRAPHICS CLEAR 1, 1, 1
    DRAW COLOR 0, 0, 0
    DRAW ALPHA 1
    DRAW LINE 0, 1 TO 1, 1
    FOR p = 1 TO scrH*2-1
      GET PIXEL 0, p COLOR v, v, v
      IF v THEN BREAK p
    NEXT p
    IF p = 1 THEN ds = 0
    IF p = 2 THEN ds = 0.5
    IF p > 2 THEN ds = p - 2

    ' Fill color and alpha
    FILL RECT 0, 0 TO 2, 2
    GET PIXEL 1, 1 COLOR fr,fg,fb,fa
    IF a < 1 THEN                      ' GET PIXEL is not 100%
      FILL ALPHA 1                     ' accurate for alpha
      FILL RECT 0, 0 TO 2, 2           ' values less than 1
      GET PIXEL 1, 1 COLOR fr,fg,fb
    END IF
  SPRITE END

  DRAW COLOR dr, dg, db
  DRAW ALPHA da
  DRAW FONT SIZE fs
  FILL ALPHA fa

  SET_GRAPHICS_MODE(gm$)

END DEF

'==============================================================

DEF SET_DRAW (r, g, b, a)

  DRAW COLOR r, g, b
  DRAW ALPHA a

END DEF

'==============================================================

DEF SET_FILL (r, g, b, a)

  FILL COLOR r, g, b
  FILL ALPHA a

END DEF

'==============================================================

'g'
/*
    IS_OPTION_SPRITE_POS_CENTRAL ()


Functions for determining the current state of OPTION SPRITE POS.

'==============================================================

IS_OPTION_SPRITE_POS_CENTRAL returns 1 if OPTION SPRITE POS is set to CENTRAL. Otherwise returns 0.

'==============================================================
*/
'' 
DEF IS_OPTION_SPRITE_POS_CENTRAL ()

  t$ = TIME()
  n1$ = "test_option_sprite_pos_1"
  n2$ = "test_option_sprite_pos_2"

  SPRITE n1$ BEGIN 5,5
    GRAPHICS CLEAR 0,0,0
  SPRITE END
  SPRITE n1$ ALPHA 0.01
  SPRITE n1$ SHOW

  SPRITE n1$ COPY n2$
  SPRITE n2$ AT 6,6
  SPRITE n2$ SHOW

  IF SPRITES_COLLIDE(n1$, n2$) THEN
    IS_OPTION_SPRITE_POS_CENTRAL = 1
  ELSE
    IS_OPTION_SPRITE_POS_CENTRAL = 0
  END IF

  SPRITE n1$ DELETE
  SPRITE n2$ DELETE

END DEF

'==============================================================

'g'
/*
    DRAW_ROUNDRECT (x1, y1, x2, y2, r)
    FILL_ROUNDRECT (x1, y1, x2, y2, r)


Functions for drawing rectangles with rounded corners.

    Uses: .pi

'==============================================================

Both functions take an input of the rectangle's top-left x,y coordinates and bottom-right x,y coordinates, and the corner radius.

  Inputs
  ------

    x1, y1    x,y-coordinates of the top-left corner
    x2, y2    x,y-coordinates of the bottom-right corner
    r         corner radius

'==============================================================

DRAW_ROUNDRECT draws a rectangle with rounded corners. This function uses only DRAW LINE and DRAW ARC commands.

FILL_ROUNDRECT fills a rectangle with rounded corners. This function uses only FILL CIRCLE and FILL RECT commands. Note: This function uses multiple fill commands that overlap in some areas. For alpha values that are less than one and non-normal graphics modes, run this command with FILL ALPHA 1 and GRAPHICS MODE NORMAL in a sprite and then stamp the sprite to the final destination with the desired graphics settings.

'==============================================================
*/
''

DEF DRAW_ROUNDRECT (x1, y1, x2, y2, r)

  pi = 2*ACOS(0)

  DRAW LINE x1+r, y1   TO x2-r, y1          ' top
  DRAW LINE x2-r, y2   TO x1+r, y2          ' bottom
  DRAW LINE x2  , y1+r TO x2  , y2-r        ' right
  DRAW LINE x1  , y2-r TO x1  , y1+r        ' left

  DRAW ARC x1+r, y1+r, r, pi    , pi*3/2    ' top-left
  DRAW ARC x2-r, y1+r, r, pi*3/2,  0        ' top-right
  DRAW ARC x2-r, y2-r, r, 0     , pi/2      ' bottom-right
  DRAW ARC x1+r, y2-r, r, pi/2  , pi        ' bottom-left

END DEF

'==============================================================

DEF FILL_ROUNDRECT (x1, y1, x2, y2, r)

  FILL CIRCLE x1+r, y1+r SIZE r         ' top-left
  FILL CIRCLE x2-r, y1+r SIZE r         ' top-right
  FILL CIRCLE x2-r, y2-r SIZE r         ' bottom-right
  FILL CIRCLE x1+r, y2-r SIZE r         ' bottom-left

  FILL RECT x1+r, y1   TO x2-r, y2      ' vertical
  FILL RECT x1  , y1+r TO x2  , y2-r    ' horizontal

END DEF

'==============================================================
Last edited by matt7 on Sun Aug 26, 2018 6:23 pm, edited 1 time in total.

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by rbytes »

Nice job! I have been looking for a better way than just popping up a field with some text.

For the Demo, a quit button would be appreciated. If there is a way to stop partway through, I couldn't find it. It is nice to come back to the demo for refreshers, but I don't always want to go through it all.

Everything works great. :D
The only thing that gets me down is gravity...

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by rbytes »

I would like to see shared code in this section for custom interface objects. I have a few examples I will post in the next week for custom sliders, buttons, switches and fields.

You did a beautiful job on the switches and sliders in GraphicsEditor. I would really like to see the code posted in this section.
The only thing that gets me down is gravity...

matt7
Posts: 115
Joined: Sun Jul 12, 2015 5:00 pm
My devices: iPhone
Location: USA

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by matt7 »

Thanks! Glad everything works well for you. I try and simulate iPad screen ratios on my iPhone during testing, but of course, that isn't the same as having an actual iPad to test on. You may find you want to tweak some of the default parameter values or even the hardcoded sizing values I have in the code. For example, anything that looks like scrW*X or scrH*Y, where X and Y are some hardcoded value between 0 and 1.
For the Demo, a quit button would be appreciated. If there is a way to stop partway through, I couldn't find it. It is nice to come back to the demo for refreshers, but I don't always want to go through it all.
Just updated the demo. It now gives the option to quit after going through an entire branch. (Whenever you are about to jump back to the front of the demo, it gives you the chance to quit.) Otherwise, if you want to quit in the middle of the demo just hit smart Basic's stop button. That's why the demo doesn't hide the toolbar.

You could create a separate exit button off in the corner, but it actually wouldn't work immediately. It could only be checked using BUTTON_PRESSED after the MSGBOX function has finished. This is one of the limitations of using this library: While the message box is visible, the only way for program execution to proceed is for the user to hit one of the buttons. Processing is completely suspended inside the library function while it waits for the user's response. (And yes, I did use SLOWDOWN in that loop.)
You did a beautiful job on the switches and sliders in GraphicsEditor. I would really like to see the code posted in this section.
Again, thank you for the high praise. At the moment, unfortunately, it would not be a trivial task to take those sliders and create a standalone library. Those sliders are deeply integrated with the rest of the code for the Gradient Editor, not to mention having to also do all the touch detection and processing (the MSGBOX function has the very simple task of just running through each button and checking if it has been pressed). The configuration, creation (drawing), touch interpretation, and processing all would need to be abstracted for the flexibility and simplicity you would want with a library function.

I like the idea though of getting some custom interface objects though!

User avatar
rbytes
Posts: 1338
Joined: Sun May 31, 2015 12:11 am
My devices: iPhone 11 Pro Max
iPad Pro 11
MacBook
Dell Inspiron laptop
CHUWI Plus 10 convertible Windows/Android tablet
Location: Calgary, Canada
Flag: Canada
Contact:

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by rbytes »

Thanks for the tips and the addition of a stop button.

I have posted a custom slider demo today, and I have a demo program almost ready for custom switches and buttons that I will post tomorrow. For the sliders I posted, you can use any two of your own images for the handle and track.

I have a fantastic program for image searching, that I find much more efficient than Google for finding what I need. It found free slider, button and switch images for me. It is called CLIPish Pro.

My sliders aren't as pretty as yours in GradientEditor, but it is nice to see a 3D shaded handle and track. Also the handle can be scaled to the screen size, something not possible with the handle on the default SB slider.

Let me know if you have any suggestions for compacting the slider code.
The only thing that gets me down is gravity...

Henko
Posts: 814
Joined: Tue Apr 09, 2013 12:23 pm
My devices: iPhone,iPad
Windows
Location: Groningen, Netherlands
Flag: Netherlands

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by Henko »

At the other end of the spectrum: a messagebox for lazy programmers😁

Code: Select all

draw font size 20
msg("This is a message box for the lazy programmer, who doesn't want to code more than the essential: the text of the message. The messagebox leaves the background intact.")
end

def msg(a$)
la=len(a$) ! fs=font_size() ! aux=0.3*la*fs*(fs+5)
get screen size w,h ! cx=w/2 ! cy=h/2
bh=floor(30+sqrt(900+aux)) ! bw=2*bh ! a=bh/4
bs=cx-bw/2 ! be=cy-bh/2
field "mess" text a$ at bs,be size bw,bh RO ML
field "mess" font size fs
field "mess" back color .8,.8,.8
xb=bs+a ! yb=be+bh-50 ! sbx=bw-2*a ! sby=40
button "msg_ok" text "ok" at xb,yb size sbx,sby
do slowdown ! until button_pressed("msg_ok")
button "msg_ok" delete ! field "mess" delete
end def
IMG_1549.PNG
IMG_1549.PNG (304.87 KiB) Viewed 6203 times

User avatar
GeorgeMcGinn
Posts: 435
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro 10.5in
IMac
Linux i386
Windows 7 & 10
Location: Venice, FL
Flag: United States of America
Contact:

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by GeorgeMcGinn »

I too have a lazy man's message box code. Actually I have several flavors.

This one builds a message string with both string data and variables, and uses it as both a message delivery and a clickable message to then do something.

Below is a very basic routine:

Code: Select all

GRAPHICS
OPTION ANGLE DEGREES
OPTION BASE 1
'SET TOOLBAR OFF
OPTION KEYBOARD ON
SET ORIENTATION LANDSCAPE
BUTTON.SELECTED=0

'*** If Filename does not exists then issue a warning message and go back
   MyFile$="FCFile.txt"
   MSG1$=""
   MSG2$="*** Filename "&MyFile$&" does not exist – press message to continue: "
   GOSUB MessageBox
   debug pause

'*** End Of Program Routine
endprog:
    STOP



MessageBox:
'-----------------------------------------------------------------
'*** Message Box Subroutine. Displays a shadowed message box where
'*** the calling routine supplies the message and whether it needs
'*** a response.
'


'*** Message Box Code
    SHADOW ON
    SHADOW ALPHA 1
    SHADOW COLOR 0,0,0
    SHADOW OFFSET 10,10
    FILL COLOR 1,1,0

'*** Message Box Text
'*** Code revised by Ricardo (rbytes)
    DRAW FONT SIZE 24
    DRAW FONT NAME "CourierNewPS-BoldMT"
    DRAW COLOR 0,0,0 
    FILL COLOR 1,1,0
    SET BUTTONS CUSTOM
    FIELD  "shadow" TEXT "" AT 50,265 SIZE 970,80 RO      ' A shadow
    FIELD  "shadow" BACK COLOR 0,0,0                      ' dark yellow
    FIELD  "shadow" BACK ALPHA 1                          ' and semi-transparent
    FIELD  "under"  TEXT MSG1$ AT 40,260 SIZE 970,80 RO   ' a rectangle
    FIELD  "under"  BACK COLOR 0,0,0                      ' colored black
    IF MSG1$="" THEN
       BUTTON "msgb"   TEXT MSG2$  AT 80,280 SIZE 870,40  ' with your button on top
    ELSE
       BUTTON "msgx"   TEXT "X"    AT 960,275 SIZE 25,30  ' X button to close box
    ENDIF
    SET BUTTONS DEFAULT

    DO
       IF BUTTON_PRESSED("msgb") THEN
          BUTTON.SELECTED=TRUE
       ENDIF
       IF BUTTON_PRESSED("quit") OR BUTTON_PRESSED("msgx") THEN
          BUTTON.SELECTED=TRUE
       ENDIF
       IF BUTTON_PRESSED("quit2") THEN
          GOTO EXIT_MessageBox
       ENDIF
       SLOWDOWN
    UNTIL BUTTON.SELECTED


EXIT_MessageBox:
    SET BUTTONS DEFAULT
    SET BUTTONS FONT SIZE 18
    FIELD "shadow" DELETE
    FIELD "under"  DELETE
    MSG1$=""!MSG2$=""
    REFRESH
    RETURN

IMG_0465.PNG
IMG_0465.PNG (454.68 KiB) Viewed 6173 times
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)

User avatar
GeorgeMcGinn
Posts: 435
Joined: Sat Sep 10, 2016 6:37 am
My devices: IPad Pro 10.5in
IMac
Linux i386
Windows 7 & 10
Location: Venice, FL
Flag: United States of America
Contact:

Re: MSGBOX Library (clone of VBA's MsgBox function)

Post by GeorgeMcGinn »

GeorgeMcGinn wrote:
Wed Sep 05, 2018 4:09 am
I too have a lazy man's message box code. Actually I have several flavors.

This one builds a message string with both string data and variables, and uses it as both a message delivery and a clickable message to then do something.

Below is a very basic routine:

EDIT: I made pushing the button end the program. Somewhere I have a buttons within a button that does a lot more. I will look for it and post it here. I know Rbytes helped on this one.

Code: Select all

GRAPHICS
OPTION ANGLE DEGREES
OPTION BASE 1
'SET TOOLBAR OFF
OPTION KEYBOARD ON
SET ORIENTATION LANDSCAPE
BUTTON.SELECTED=0

'*** If Filename does not exists then issue a warning message and go back
   MyFile$="FCFile.txt"
   MSG1$=""
   MSG2$="*** Filename "&MyFile$&" does not exist – press message to continue: "
   GOSUB MessageBox

'*** End Of Program Routine
endprog:
    STOP



MessageBox:
'-----------------------------------------------------------------
'*** Message Box Subroutine. Displays a shadowed message box where
'*** the calling routine supplies the message and whether it needs
'*** a response.
'


'*** Message Box Code
    SHADOW ON
    SHADOW ALPHA 1
    SHADOW COLOR 0,0,0
    SHADOW OFFSET 10,10
    FILL COLOR 1,1,0

'*** Message Box Text
'*** Code revised by Ricardo (rbytes)
    DRAW FONT SIZE 24
    DRAW FONT NAME "CourierNewPS-BoldMT"
    DRAW COLOR 0,0,0 
    FILL COLOR 1,1,0
    SET BUTTONS CUSTOM
    FIELD  "shadow" TEXT "" AT 50,265 SIZE 970,80 RO      ' A shadow
    FIELD  "shadow" BACK COLOR 0,0,0                      ' dark yellow
    FIELD  "shadow" BACK ALPHA 1                          ' and semi-transparent
    FIELD  "under"  TEXT MSG1$ AT 40,260 SIZE 970,80 RO   ' a rectangle
    FIELD  "under"  BACK COLOR 0,0,0                      ' colored black
    IF MSG1$="" THEN
       BUTTON "msgb"   TEXT MSG2$  AT 80,280 SIZE 870,40  ' with your button on top
    ELSE
       BUTTON "msgx"   TEXT "X"    AT 960,275 SIZE 25,30  ' X button to close box
    ENDIF
    SET BUTTONS DEFAULT

    DO
       IF BUTTON_PRESSED("msgb") THEN
'          BUTTON.SELECTED=TRUE
          GOTO EXIT_MessageBox
       ENDIF
       IF BUTTON_PRESSED("quit") OR BUTTON_PRESSED("msgx") THEN
'          BUTTON.SELECTED=TRUE
          GOTO EXIT_MessageBox
       ENDIF
       IF BUTTON_PRESSED("quit2") THEN
          GOTO EXIT_MessageBox
       ENDIF
       SLOWDOWN
    UNTIL BUTTON.SELECTED


EXIT_MessageBox:
    SET BUTTONS DEFAULT
    SET BUTTONS FONT SIZE 18
    FIELD "shadow" DELETE
    FIELD "under"  DELETE
    MSG1$=""!MSG2$=""
    REFRESH
    RETURN

IMG_0465.PNG
George McGinn
Computer Scientist/Cosmologist/Writer/Photographer
Member: IEEE, IEEE Computer Society
IEEE Sensors Council & IoT Technical Community
American Association for the Advancement of Science (AAAS)

Post Reply