Library functions: interactive functions (console)

This class includes all the functions that can be used to create a direct interaction with the user: formatted output to the screen, keyboard input, etc.
These functions are specific to the interactive version of Proteus, for which the directive INTERACTIVE is defined.

Many functions described below require constant values for parameters, defined in the file console.prt, that should be included whenever one of the functions in this class is used.

The functions are divided in the following categories:

Input of single keystrokes (low level):

SETKEY(nKey, UDF)

runs UDF (which does not take any parameter) every time that nKey is pressed during a call to GETCH; the result of the UDF becomes the new value for GETCH (if 0, the key is ignored)

UNSETKEY(nKey)

removes the association between nKey and an UDF (see SETKEY)

STUFFKEY(nKey)

stuffs nKey in the keyboard buffer

GETCH([nSeconds])

waits for a keypress for nSeconds (or endlessly, if nSeconds is not specified); returns 0 if the timeout expired, the key pressed otherwise; this function honors SETKEY and STUFFKEY

KBDHIT()

returns a number different from 0 if there is a key pending in the keyboard buffer, 0 otherwise; this function honors STUFFKEY

Buzzer:

BEEP(nFrequency, nDuration)

emits the specified tone (nFrequency, in hertz) for the specified duration (nDuration, in milliseconds)

Parameters for video input/output:

DISPPARSAVE()

saves all video attributes in a string, which is returned by the function; use DISPPARRESTORE to restore video attributes

DISPPARRESTORE(cParameters)

restores video attributes from the string cParameters; this string should be the result of a previous call to DISPPARSAVE

DISPSET(nParameter, value)

sets the value of a video attribute; returns the previous value, which can also be obtained by using DISPGET.
The possible values for nParameter are listed in console.prt; in the following table you will find the name of the constants, that should always be used after including console.prt at the beginning of the script:

Parameter Meaning
DISP_XSTART horizontal offset automatically added to each X coordinate in video functions; default is 0. Useful to reposition all the masks without manually changing all the coordinates.
DISP_YSTART vertical offset automatically added to each Y coordinate in video functions; default is 0. Useful to reposition all the masks without manually changing all the coordinates.
DISP_CURSOR cursor size; possible values are DISP_CUR_OFF (no cursor), DISP_CUR_BIG (blinking block), DISP_CUR_SMALL (underscore, default)
DISP_CURX X coordinate for the cursor; default is current position
DISP_CURY Y coordinate for the cursor; default is current position
DISP_MAXCOL maximum X value for the screen; determined by current video mode
DISP_MAXROW maximum Y value for the screen; determined by current video mode
DISP_JUST justification for video output, used by DISP[E]OUT and DISP[E]WRITE; possible values are:
  • DISP_JUST_NONE: no justification (default)
  • DISP_JUST_LEFT: justify to the left
  • DISP_JUST_CENTER: center
  • DISP_JUST_RIGHT: justify to the right
  • DISP_JUST_PACK: packet

If justification is different than DISP_JUST_NONE, the value for DISP_JLEN is used for justification length

DISP_JLEN justification length; by default, it is set to the maximum width of the screen decremented by the value for DISP_XSTART
DISP_FOREG text colour (default: LIGHTGRAY)
DISP_UNSFG unselected text colour (default: DARKGRAY)
DISP_SELFG selected text colour (default: LIGHTGREEN)
DISP_BACKG background colour (default: BLACK)
DISP_SELBG selected background colour (default: LIGHTGRAY)
DISP_BUTFG button text colour (default: LIGHTGRAY)
DISP_BUTBG button background colour (default: BLACK)
DISP_SBUTFG selected button text colour (default: BLACK)
DISP_SBUTBG selected button background colour (default: LIGHTGRAY)
DISP_TITLEFG title text colour (default: LIGHTRED)
DISP_TITLEBG title background colour (default: LIGHTGRAY)
DISP_SCORE scoreboard enabled/disabled (the scoreboard is a descriptive text for menu options; default is 0, that is disabled)
DISP_SCRFG scoreboard text colour (default: BLACK)
DISP_SCRBG scoreboard background colour (default: LIGHTGRAY)
DISP_SCRX X coordinate for scoreboard
DISP_SCRY Y coordinate for scoreboard
DISP_SCRLEN scoreboard length
DISP_SCRJUST scoreboard justification (see DISP_JUST for possible values)
DISP_FRAME frame enabled/disabled (for DISPBOX, DISPMENU, DISPLIST, DISPALERT, DISPOSD; default: 1 = enabled)
DISP_FRAMEFG frame text colour (default: LIGHTGRAY)
DISP_FRAMEBG frame background colour (default: BLACK)
DISP_FRAMECH characters to be used for the frame; the string should be 8 character long, which represent:
  • 1 - upper left corner
  • 2 - upper size
  • 3 - upper right corner
  • 4 - right side
  • 5 - lower right corner
  • 6 - lower side
  • 7 - lower left corner
  • 8 - left side

A few possible values are:

  • DISP_FRAME_SINGLE: single line frame (default)
  • DISP_FRAME_DOUBLE: double line frame
  • DISP_FRAME_SNGDOU: single line (upper and lower side) and double line (left and right side) frame
  • DISP_FRAME_DOUSNG: double line (left and right side) and single line (left and right side) frame
  • DISP_FRAME_DOTS: dotted frame
DISP_FRAME3D 3D effect for frame enabled/disabled (default: 1 = enabled)
DISP_LISTSEL selection character for lists; a few possible values are:
  • DISP_LISTSEL_ARR: single right arrow (default)
  • DISP_LISTSEL_CHK: check symbol
  • DISP_LISTSEL_SQR: little square
  • DISP_LISTSEL_DAR: double right arrow
  • DISP_LISTSEL_GT: symbol '>'
DISP_SHADOW type of shadow for boxes; possible values are:
  • DISP_SHADOW_NONE: no shadow
  • DISP_SHADOW_LEFT: shadow to the left
  • DISP_SHADOW_RIGHT: shadow to the right (default)
DISP_PATTERN fill character, used to fill frames, clear screen, justify strings; default: space (ascii 32)
DISP_BLINK enable blinking or high intensity background; available only for the Dos version of Proteus (under Windows™, blinking is always disabled); possible values are:
  • DISP_BLINK_OFF: no blinking, high intensity background (default)
  • DISP_BLINK_ON: blinking enabled, low intensity background
DISP_SOUND enable or disable warning beep for editing functions (for using with telnet servers); default: 1 (sound enabled)
DISP_THUMBCH characters to be used for drawing the thumb elevator (column indicating the position of an item within a list); default value is DISP_THUMB_STD; the string is 4-character long:
  • 1 - upper column delimiter
  • 2 - lower column delimiter
  • 3 - filler
  • 4 - position indicator
DISP_EOLWRAP enable or disable wrap at end-of-line (and scrolling at the end of the screen); default: 1 (=enabled)

Colour table:

Value Sample
BLACK  
BLUE  
GREEN  
CYAN  
RED  
MAGENTA  
BROWN  
LIGHTGRAY  
DARKGRAY  
LIGHTBLUE  
LIGHTGREEN  
LIGHTCYAN  
LIGHTRED  
LIGHTMAGENTA  
YELLOW  
WHITE  

DISPGET(nParameter)

returns the current value of the attribute; see DISPSET for a description of nParameter

DISPATTRIB(nX, nY, @nFGColour, @nBGColour)

returns the foreground (nFGColour) and the background colour (nBGColour) found at coordinate nX, nY on the screen

RESIZE(nX, nY)

changes the size of the video console to nX, nY; the Windows™ version allow any positive value; the Dos version ignores nX (always 80) and approximates nY to the nearest value among: 25, 43, 50

Video output:

DISPCOLORIZE(nX1, nY1, nX2, nY2, nFGColour, nBGColour)

paints the area of the screen delimited by nX1, nY1 and nX2, nY2 with colours nFGColour (foreground) and nBGColour (background)

DISPINVERT(nX1, nY1, nX2, nY2)

inverts the colours in the area of the screen delimited by nX1, nY1 and nX2, nY2

DISPSAVE(nX1, nY1, nX2, nY2)

returns a string that can be used by DISPRESTORE to restore the rectangular video area delimited by nX1, nY1 and nX2, nY2

DISPRESTORE(nX1, nY1, nX2, nY2, cImage)

restores the area cImage (which was returned by DISPSAVE) from nX1, nY1 to nX2, nY2; the values nX1, nY1, nX2, nY2 can be different from those used in the call to DISPSAVE; however, the differences nX2 - nX1 and nY2 - nY1 must be identical to the differences between the parameters in the call to DISPSAVE; in other words, the length of the sides of the area delimited by DISPSAVE must be the same as the length of the sides in the area specified in the call to DISPRESTORE

DISPCLEAR(nX1, nY1, nX2, nY2[, nBGColour[, cPattern]])

clears the area delimited by nX1, nY1 and nX2, nY2 by using the character DISP_PATTERN (or cPattern, if specified) and the background colour nBGColour (or DISP_BACKG)

DISPCLS()

clears the screen by using the character DISP_PATTERN and the background colour DISP_BACKG

DISPHSCROLL(nX1, nY1, nX2, nY2, nOffset)

horizontally scrolls by nOffset characters (positive = scrolls to the left, negative = scrolls to the right) the area delimited by nX1, nY1 and nX2, nY2

DISPVSCROLL(nX1, nY1, nX2, nY2, nOffset)

vertically scrolls by nOffset rows (positive = scrolls to the top, negative = scrolls to the bottom) the area delimited by nX1, nY1 and nX2, nY2

DISPBOX(nX1, nY1, nX2, nY2)

paints a box from nX1, nY1 to nX2, nY2 using the current attributes for line, shadow and frame

DISPLINE(nX1, nY1, nX2, nY2[, cOCharVChar])

paints a line from nX1, nY1 to nX2, nY2, where nX1 = nX2 or nY1 = nY2; the first character of cOCharVChar is used if the line is horizontal, the second character if it is vertical; if cOCharVChar is not specified, the characters 2 and 4 from DISPGET(DISP_FRAMECH) are used

DISPWRITE(nX, nY, cText)

writes cText at nX, nY using current values for colour (DISP_FOREG/DISP_BACKG) and justification (DISP_JUST/DISP_JLEN)

DISPEWRITE(nX, nY, cText)

writes cText at nX, nY using current values for colour (DISP_FOREG/DISP_BACKG) and justification (DISP_JUST/DISP_JLEN); each character prefixed by "~" in cText is highlighted

DISPOUT(cText)

writes cText at current position, using current values for colour (DISP_FOREG/DISP_BACKG) and justification (DISP_JUST/DISP_JLEN)

DISPEOUT(cText)

writes cText at current position, using current values for colour (DISP_FOREG/DISP_BACKG) and justification (DISP_JUST/DISP_JLEN); each character prefixed by "~" in cText is highlighted

DISPOSD(cText)

paints a box in the center of the screen with the string cText, using current values for colour (DISP_FOREG/DISP_BACKG) and justification (DISP_JUST/DISP_JLEN); returns a string that can be used by DISPRESTOREOSD to restore the area overwritten by the box

DISPRESTOREOSD(cImage)

restores the screen modified by DISPOSD; cImage is the value returned by a previous call to DISPOSD

Input from keyboard (high level):

GETSTRING(nX, nY, @cDefault, nMaxLength, nWinLength, @nStartPos, @nWinOffset, @nInsert, cPicture)

reads a string from the keyboard; the input line starts at nX, nY and is nWinLength character long; the maximum length for the input string is nMaxLength and its initial value is cDefault. nStartPos is the starting position of the cursor within the string (should be 0 on first call); nWinOffset is the offset of the input window within the input buffer (should be 0 on first call); nInsert is the status: 1 = insert, 0 = overwrite.

cPicture is the format string for validating the input; it can include the following characters:

Character Meaning
! converts all lowercase characters to upper case
* prints '*' in place of any character typed
N accepts only an integer number
F accepts an integer or floating point number
D accepts only valid date
H accepts only valid time
Mc mask for data input; c can include the following characters:

X = any character
N = digit 0-9
O = digit 0-7
H = digit 0-9 or A-H
B = digit 0 or 1
A = alphabetic character
U = alphanumeric character
other = literal character

RxExp xExp extended regular expression
TxExp xExp case-unsensitive extended regular expression
PrExp rExp simple regular expression
OrExp rExp case-unsensitive simple regular expression

This function accepts cursor keys, Home, End, Ins, Del, Backspace, Enter, Esc, with the usual meanings; it returns 1 if the user confirms editing (Enter), 0 otherwise. In any case, the following parameters are updated by reference: cDefault, nStartPos, nWinOffset and nInsert.

GETSTRINGUDF(nX, nY, @cDefault, nMaxLength, nWinLength, @nStartPos, @nWinOffset, @nInsert, cPicture, READER)

reads a string from the keyboard; the input line starts at nX, nY and is nWinLength character long; the maximum length for the input string is nMaxLength and its initial value is cDefault. nStartPos is the starting position of the cursor within the string (should be 0 on first call); nWinOffset is the offset of the input window within the input buffer (should be 0 on first call); nInsert is the status: 1 = insert, 0 = overwrite.

The UDF READER is called at every key press and accepts two parameters: nKey (key value) and cValue (current value of input string):

READER(@nKey, @cValue)

The values returned by the UDF are interpreted according to the following table:

Value Meaning
0 accept the character and add it to the string
1 string updated - display buffer and continue editing
2 string updated - display buffer and confirm editing
3 abort editing
4 confirm editing
5 ignore the character
6 go to previous character
7 go to next character
8 go to start of string
9 go to end of string

This function returns 1 if the user confirms editing (Enter), 0 otherwise. In any case, the following parameters are updated by reference: cDefault, nStartPos, nWinOffset and nInsert.

GETTEXT(nX, n Y, @cDefault, nRows, nCols, @nStartPos, @nInsert)

function for editing a rectangular text buffer; the following table describes the parameters:

Parameter Meaning
nX, nY upper left corner coordinates
cDefault initial value for the buffer
nRows number of rows
nCols number of columns
nStartPos start position of cursor within the rectangular buffer (nRows x nCols)
nInsert insert/overwrite status

The character SCR = CHR(255) is used to delimit paragraphs. The following table summarizes the keys accepted:

Key Meaning
CTRL-Enter/Ctrl-W/Enter on the last line confirm editing
ESC abort editing
Cursor keys navigate area
Home/End start/end of line
CTRL-home/end start/end of buffer
CTRL-left/right next/previous word
Delete delete the current character and move backwards the following text
Backspace delete the previous character and move backwards the following text
ESC exit and return the modified buffer
Return if insert is enabled, introduce spaces until the end of the line (what follows is taken to the next line); otherwise, SCR is inserted at the end of the current line (if possible)
CTRL-Y delete current line
Ins change between insert and overwrite; in insert mode every character introduced moves all the following text to the right
CTRL-B show/hide paragraph symbols
CTRL-Z take to the following line (wrap) the word to the left of the cursor
CTRL-E take the cursor to the end of the word being edited
CTRL-N reset buffer and take cursor to the beginning
CTRL-S checkpoint (copy the actual buffer to a backup in memory)
CTRL-L restore buffer to the last checkpoint

The paragraphs are managed by inserting the symbol SCR in the text; the character CHR(255) is similar to blank, so it is not displayed or printed (it is invisible); for this reason, the buffer is always returned with this character as the paragraph delimiter.
This function returns 1 if the user confirmed editing, 0 otherwise.
cDefault, nStartPos and nInsert are always updated by reference when the function returns.

GETTEXTUDF(nX, nY, @cDefault, nRows, nCols, @nStartPos, @nInsert, READER)

function for editing a rectangular text buffer; the following table describes the parameters:

Parameter Meaning
nX, nY upper left corner coordinates
cDefault initial value for the buffer
nRows number of rows
nCols number of columns
nStartPos start position of cursor within the rectangular buffer (nRows x nCols)
nInsert insert/overwrite status

The character SCR = CHR(255) is used to delimit paragraphs.
Every key pressed by the user is passed to the UDF READER, which accepts two parameters, passed by reference: nKey (key pressed) and cValue (current value for editing buffer):

READER(@nKey, @cValue)

The UDF can return the following values:

Value Meaning
0 accept the character into the buffer
1 text updated - display and continue editing
2 text updated - diplay and confirm editing
3 abort editing
4 confirm editing
5 ignore the character
6 move cursor to previous character
7 move cursor to next character
8 move cursor to start of text
9 move cursor to end of text
10 delete current line
11 move cursor to start of line
12 move cursor to end of line
13 move cursor to previous word
14 move cursor to next word
15 hide/display paragraph symbols
16 take to the following line (wrap) the word to the left of the cursor
17 take the cursor to the end of the word being edited
18 reset buffer and take cursor to the beginning
19 restore buffer to the last checkpoint
20 checkpoint

The paragraphs are managed by inserting the symbol SCR in the text; the character CHR(255) is similar to blank, so it is not displayed or printed (it is invisible); for this reason, the buffer is always returned with this character as the paragraph delimiter.
This function returns 1 if the user confirmed editing, 0 otherwise.
cDefault, nStartPos and nInsert are always updated by reference when the function returns.

DISPMENU(nX, nY, vOptions, vSelectable, @nFirst)

display a menu of choices, from which the user can choose one; the following table summarizes the parameters:

Parameter Meaning
nX, nY upper left corner of the menu
vOptions handle of an array, returned by a call to VECCREATE, as in the following example:

VECCREATE("text1|description1", "text2|description2")

if textx is empty, descriptionx is the character user to draw an empty line; in this way, it is possible to insert separators between options
vSelectable -1 (all the options are selectable) or handle of an array (whose items are 0 or 1) returned by a call to VECCREATE, as in the following example:

VECCREATE(1,0)

1 means "selectable option", 0 "unselectable option"
nFirst number of predefined option; when the function returns, this variable is updated with the selected option

This function accepts the following keys: Home, End, cursor keys, Enter, Esc, with the usual meanings. The description of every option is displayed on the scoreboard (if it is enabled).

It returns 1 if the user selected an option, -1 if the handle vOptions is invalid or empty, 0 otherwise. On return, nFirst is updated with the number of the selected option.

DISPMENUUDF(nX, nY, vOptions, vSelectable, @nFirst, READER)

display a menu of choices, from which the user can choose one; the following table summarizes the parameters:

Parameter Meaning
nX, nY upper left corner of the menu
vOptions handle of an array, returned by a call to VECCREATE, as in the following example:

VECCREATE("text1|description1", "text2|description2")

if textx is empty, descriptionx is the character user to draw an empty line; in this way, it is possible to insert separators between options
vSelectable -1 (all the options are selectable) or handle of an array (whose items are 0 or 1) returned by a call to VECCREATE, as in the following example:

VECCREATE(1,0)

1 means "selectable option", 0 "unselectable option"
nFirst number of predefined option; when the function returns, this variable is updated with the selected option

The description of every option is displayed on the scoreboard (if it is enabled). Every key pressed by the user is passed to the UDF READER, which accepts four parameters, passed by reference:

nOpReq = READER(@nKey, @nCurrentOption, @vOptions, @vSelectable)
Parameter Meaning
nKey key pressed by the user
nCurrentOption current option
vOptions array of options
vSelectable array of selectable/unselectable options

The UDF can return the following values:

Value Meaning
0 process the key
1 ignore the key
2 select nCurrentOption, return its position in the array of options
3 highlight nCurrentOption, which becomes the current option
4 move to the next option
move to the previous option
6 move to the first option
7 move to the last option
8 return -1
9 select option and keep menu on screen
10 rebuild menu

This function returns 1 if the user selected an option, -1 if the handle vOptions is invalid or empty, 0 otherwise. On return, nFirst is updated with the number of the selected option.

DISPLIST(vOptions, nX, nY, cTitle, nRows, nLength, @nFirstSel, bSelection, @nStartLine)

display a list of options, from which the user can select one or more values; the behaviour is determined by bSelection; the following table summarizes the parameters:

Parameter Meaning
vOptions handle of an array, returned by a call to VECCREATE as in this example:

VECCREATE("text1", "text2")
nX, nY upper left corner of the box holding the options
cTitle box title (displayed only if the frame is enabled)
nRows maximum number of options displayed alltogether (if less than the number of options, the contents of the box will scroll and a thumb elevator will appear on the right side of the frame)
nLength pad length for options; if 0, the length of the longest option will be used
nFirstSel predefined option number; this variable will be updated with the number of the option selected; by default, it should be 1
bSelection -1 or handle of a bitmap returned by a call to BITMAPNEW; if it is not -1, multiple choices are allowed
nStartLine line where the selected option will be displayed (default: 0)

This function accepts the following keys: Home, End, Enter (select [if multiple selections are allowed] or accept the current option), space (enabled only if multiple selections are allowed; same as typing Enter followed by cursor down), Esc, Ctrl+Enter (enabled only if multiple selections are allowed: accept selection), cursor keys, Tab (select or de-select all options).

This function returns 1 (multiple selections) or the number of the option (starting from 1) if the user selected an option, -1 if the handle vOptions or bSelection is invalid or empty, 0 otherwise (Esc).
On return, nFirstSel is updated with the number of the selected option and bSelection with the selection map.

DISPLISTUDF(vOptions, nX, nY, cTitle, nRows, nLength, @nFirstSel, bSelection, @nStartLine, READER)

display a list of options, from which the user can select one or more values; the behaviour is determined by bSelection; the following table summarizes the parameters:

Parameter Meaning
vOptions handle of an array, returned by a call to VECCREATE as in this example:

VECCREATE("text1", "text2")
nX, nY upper left corner of the box holding the options
cTitle box title (displayed only if the frame is enabled)
nRows maximum number of options displayed alltogether (if less than the number of options, the contents of the box will scroll and a thumb elevator will appear on the right side of the frame)
nLength pad length for options; if 0, the length of the longest option will be used
nFirstSel predefined option number; this variable will be updated with the number of the option selected; by default, it should be 1
bSelection -1 or handle of a bitmap returned by a call to BITMAPNEW; if it is not -1, multiple choices are allowed
nStartLine line where the selected option will be displayed (default: 0)

Every key pressed by the user is passed to the UDF READER, which accepts four parameters, the first two passed by reference:

nOpReq = READER(@nKey, @nCurrentOption, @vOptions, bSelection)
Parameter Meaning
nKey key pressed by the user
nCurrentOption current option
vOptions array of options
bSelection bitmap holding selection status

The UDF can return one of the following values:

Value Meaning
0 process key
1 ignore key
2 select nCurrentOption; if bSelection is -1, return the number of the option in the array
3 return the current option or 1 (multiple selection); the option box is removed from screen
4 return the current option or 1 (multiple selection); the option box is left on screen
5 return -1; the option box is removed from screen
6 return -1; the option box is left on screen
7 highlight nCurrentOption, which becomes the current option
8 move to the next option
9 move to the previous option
10 move to the first option
11 move to the last option
12 rebuild the list of options

This function returns 1 (multiple selections) or the number of the option (starting from 1) if the user selected an option, -1 if the handle vOptions or bSelection is invalid or empty, 0 otherwise (Esc).
On return, nFirstSel is updated with the number of the selected option and bSelection with the selection map.

DISPALERT(cText, vButtons)

display a message (cText) in the center of the screen, together with one or more keys whose descriptions are specified in the array vButtons; the following table summarizes the parameters:

Parameter Meaning
cText text to be displayed
vButtons handle of an array, returned by a call to VECCREATE, as in this example:

VECCREATE("key1", "key2")

This function accepts the following keys: cursor keys, space or Enter (accept selection), Esc (abort), Tab (cycle between buttons).
It returns the number of the button selected (> 0) or 0 (Esc).

DISPALERTUDF(cText, vButtons, READER)

display a message (cText) in the center of the screen, together with one or more keys whose descriptions are specified in the array vButtons; the following table summarizes the parameters:

Parameter Meaning
cText text to be displayed
vButtons handle of an array, returned by a call to VECCREATE, as in this example:

VECCREATE("key1", "key2")

Every key pressed by the user is passed to the UDF READER, which accepts two parameters, passed by reference:

nOpReq = READER(@nKey, @nCurrentButton)

The UDF can return one of the following values:

Value Meaning
0 process nKey
1 select current button and return (box is removed)
2 select current button and return (box is left on screen)
3 abort and remove box
4 abort and leave box
5 next button
6 previous button
7 first button
8 last button

This function returns the number of the button selected (> 0) or 0 (Esc).

Start of page Next topic Previous topic Contents Index
Midnight Lake iPhone Case Black Women Shoes Black Flat Shoes Leather Flats Black Patent Ballerinas Black Ballet Shoes Casual Shoes Black Shoes Women Balle Record Player Cufflinks Best iPhone XR Clear Cases iPhone XS/XS Max Leather Cases Sale Best iPhone 8/8 Plus Silicone Cases iPhone 7/7 Plus Cases & Screen Protector New Cases For iPhone 6/6 Plus iPhone 8 Case Sale iPhone Xr Case Online iPhone 7 Case UK Online iPhone X Case UK Sale iPhone X Case Deals iPhone Xs Case New Case For iPhone Xr UK Online Case For iPhone 8 UK Outlet Fashion Silver Cufflinks For Men Best Mens Cufflinks Outlet Online The Gold Cufflinks Shop Online Cheap Shirt Cufflinks On Sale Nice Wedding Cufflinks UK Online Top Black Cufflinks UK Online Mens Cufflinks Online Silver Cufflinks For Men Men Cufflinks UK Sale Gold Cufflinks UK Online Gold Cufflinks UK Silver Cufflinks UK Shirt Cufflinks Discount Online Mens Cufflinks Deals & Sales Girls Shoes For Dance Fashion Ballet Dance Shoes Best Ballet Flats Shoes UK Online Cheap Ballet Pointe Shoes UK Online Best Ballet Shoes Outlet Best Dance Shoes Sale Cheap Ballet Flats Sale UK Best Pointe Shoes Online UK Ballet Dance Shoes UK Shoes For Dance UK Best Ballet Slippers Shop Best Yoga Shoes Hotsell