REM >BASIC:Icon
REM
REM Copyright 2001-2014, Stephen Fryatt (info@stevefryatt.org.uk)
REM
REM This file is part of WimpLib:
REM
REM   http://www.stevefryatt.org.uk/software/
REM
REM Licensed under the EUPL, Version 1.2 only (the "Licence");
REM You may not use this work except in compliance with the
REM Licence.
REM
REM You may obtain a copy of the Licence at:
REM
REM   http://joinup.ec.europa.eu/software/page/eupl
REM
REM Unless required by applicable law or agreed to in
REM writing, software distributed under the Licence is
REM distributed on an "AS IS" basis, WITHOUT WARRANTIES
REM OR CONDITIONS OF ANY KIND, either express or implied.
REM
REM See the Licence for the specific language governing
REM permissions and limitations under the Licence.
:
REM Icon handling library
REM
REM The variable a% is reqired to point to 256 bytes of memory.


REM Return the text from an icon, whether indirected or not.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			The text contained in the icon.
:
DEF FNicon_get_text(!a%, a%!4)
LOCAL string$, length%, ptr%, char%

SYS "Wimp_GetIconState",,a%

IF (a%!24 AND &100) = 0 THEN
	ptr% = a% + 28
	length% = 0
	string$ = ""

	REPEAT
		char% = ptr%?length%
		IF (char% >= 32) THEN string$ += CHR$(char%)
		length% += 1
	UNTIL (char% < 32) OR (length% > 12)
ELSE
	string$ = FNstring_read(a%!28)
ENDIF
=string$


REM Get the address of an icon's indirected text buffer.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			Pointer to the buffer, or 0 if not indirected.
:
DEF FNicon_indirection(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
IF (a%!24 AND &100) = 0 THEN =0
=a%!28


REM Get the address of an icon's validation string (assuming indirected and
REM text flag set).
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			Pointer to the string, or 0 if not available.
:
DEF FNicon_validation(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
IF (a%!24 AND &101) <> &101 THEN =0
=a%!32


REM Set the contents of an icon's indirected text buffer.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to set.
REM \param text$		The text to write to the icon.
:
DEF PROCicon_set_indirected_text(!a%, a%!4, text$)
SYS "Wimp_GetIconState",,a%
IF ((a%!24 AND &100) = 0) OR (a%!28 = 0) THEN ENDPROC
$(a%!28) = LEFT$(text$, a%!36 - 1)
ENDPROC


REM Get the content of a command from an icon's validation string.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \param command$		The command for which to return the value.
REM \return			The content of the command, or "" if not found.
:
DEF FNicon_validation_command(window%, icon%, command$)
LOCAL validation%, start%, found%, ucase%, text$

validation% = FNicon_validation(window%, icon%)
IF validation% = 0 THEN = ""

SYS "Territory_UpperCaseTable", -1 TO ucase%

command$ = CHR$(ucase%?ASC(command$))

start% = TRUE
found% = FALSE
text$ = ""

WHILE (?validation% >= 32) AND (?validation% <> ASC(";") OR found% = FALSE)
	IF ?validation% = ASC(";") THEN
		start% = TRUE
	ELSE
		IF start% AND (CHR$(ucase%?(?validation%)) = command$) THEN
			found% = TRUE
		ELSE
			IF found% THEN text$ += CHR$(?validation%)
		ENDIF

		start% = FALSE
	ENDIF

	validation% += 1
ENDWHILE
=text$


REM Get the selected state of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			TRUE if the icon is selected; FALSE if not.
:
DEF FNicon_selected(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
=((a%!24 AND &200000) <> 0)


REM Get the shaded state of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			TRUE if the icon is shaded; FALSE if not.
:
DEF FNicon_shaded(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
=((a%!24 AND &400000) <> 0)


REM Get the background Wimp colour of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			The Wimp colour of the icon's background
:
DEF FNicon_background_colour(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
=((a%!24 AND &F0000000) >>> 28)


REM Get the foreground Wimp colour of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon of interest.
REM \return			The Wimp colour of the icon's foreground
:
DEF FNicon_foreground_colour(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
=((a%!24 AND &0F000000) >>> 24)


REM Set the selected, shaded and deleted states of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \selected%			TRUE to select the icon; FALSE to deselect it.
REM \shaded%			TRUE to shade the icon; FALSE to unshade it.
REM \deleted%			TRUE to delete the icon; FALSE to undelete it.

DEF PROCicon_set_state(!a%, a%!4, selected%, shaded%, deleted%)
LOCAL eor%, clear%

IF selected% THEN clear% += &200000 : eor% += &200000 ELSE clear% += &200000
IF shaded% THEN clear% += &400000 : eor% += &400000 ELSE clear% += &400000
IF deleted% THEN clear% += &800000 : eor% += &800000 ELSE clear% += &800000
a%!8 = eor%
a%!12 = clear%
SYS "Wimp_SetIconState",,a%
ENDPROC


REM Set the selected state of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \selected%			TRUE to select the icon; FALSE to deselect it.
:
DEF PROCicon_set_selected(!a%, a%!4, selected%)
LOCAL eor%, clear%

IF selected% THEN clear% += &200000 : eor% += &200000 ELSE clear% += &200000
a%!8 = eor%
a%!12 = clear%
SYS "Wimp_SetIconState",,a%
ENDPROC


REM Set the shaded state of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \shaded%			TRUE to shade the icon; FALSE to unshade it.
:
DEF PROCicon_set_shaded(!a%, a%!4, shaded%)
LOCAL eor%, clear%

IF shaded% THEN clear% += &400000 : eor% += &400000 ELSE clear% += &400000
a%!8 = eor%
a%!12 = clear%
SYS "Wimp_SetIconState",,a%
ENDPROC


REM Set the deleted state of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \deleted%			TRUE to delete the icon; FALSE to undelete it.
:
DEF PROCicon_set_deleted(!a%, a%!4, deleted%)
LOCAL eor%, clear%

IF deleted% THEN clear% += &800000 : eor% += &800000 ELSE clear% += &800000
a%!8 = eor%
a%!12 = clear%
SYS "Wimp_SetIconState",,a%
ENDPROC


REM Set the foreground and background colours of an icon.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \param foreground%		The foreground Wimp colour for the icon.
REM \param background%		The background Wimp colour for the icon.
:
DEF PROCicon_set_colours(!a%, a%!4, foreground%, background%)
LOCAL eor%, clear%

a%!8 = 0
a%!12 = &FF000000
SYS "Wimp_SetIconState",,a%

a%!8 = (background% << 28) + (foreground% << 24)
a%!12 = a%!8
SYS "Wimp_SetIconState",,a%
ENDPROC


REM Increment the numeric value in an icon by one, up to a given limit.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \param limit%		The maximum value to increment to.
:
DEF PROCicon_increment_value(window%, icon%, limit%)
LOCAL value%

value% = VAL($FNicon_indirection(window%, icon%))
value% += 1
IF value% <= limit% THEN $FNicon_indirection(window%, icon%) = STR$(value%)
PROCicon_redraw(window%, icon%)
ENDPROC


REM Decrement the numeric value in an icon by one, down to a given limit.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \param limit%		The minimum value to decrement to.
:
DEF PROCicon_decrement_value(window%, icon%, limit%)
LOCAL value%

value% = VAL($FNicon_indirection(window%, icon%))
value% -= 1
IF value% >= limit% THEN $FNicon_indirection(window%, icon%) = STR$(value%)
PROCicon_redraw(window%, icon%)
ENDPROC


REM Bump a numeric value in an icon by one in a given direction, between limits.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be updated.
REM \direction%			TRUE to increase the value; FALSE to decrease.
REM \param min%			The minimum range for the icon, inclusive.
REM \param max%			The maximum range for the icon, inclusive.
REM \param pad%			The length to which to pad the number with
REM				leading zeros, or 0 for none.
:
DEF PROCicon_bump_value(window%, icon%, direction%, min%, max%, pad%)
LOCAL val%, val$

val$ = $FNicon_indirection(window%, icon%)
val% = VAL(val$)

IF direction% THEN
	val% += 1
	IF val% <= max% THEN val$ = STR$(val%)
ELSE
	val% -= 1
	IF val% >= min% THEN val$ = STR$(val%)
ENDIF

IF pad% > 0 THEN val$ = RIGHT$(STRING$(pad%, "0") + val$, pad%)

$FNicon_indirection(window%, icon%) = val$

SYS "Wimp_GetCaretPosition",,a%
IF !a% = window% AND a%!4 = icon% THEN SYS "Wimp_SetCaretPosition", window%, icon%,,, -1, LEN(val$)
PROCicon_redraw(window%, icon%)
ENDPROC


REM Place the caret at the end of an icon, or give a window focus.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to take the caret, or
REM 				-1 to give a window focus on the work area.
:
DEF PROCicon_put_caret_at_end(window%, icon%)
PROCicon_put_caret(window%, icon%, -1)
ENDPROC


REM Place the caret at the end of an icon, or give a window focus.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to take the caret, or
REM 				-1 to give a window focus on the work area.
REM \param position%		The index into the text at which to place the
REM				caret, or -1 to place at the end.
:
DEF PROCicon_put_caret(!a%, a%!4, position%)
LOCAL text$, length%

IF a%!4 > -1 THEN
	SYS "Wimp_GetIconState",,a%
	SYS "XOS_GenerateError", a%!28 TO text$
	length% = LEN(text$)
	IF position% < 0 OR position% > length% THEN position% = length%
ELSE
	position% = 0
ENDIF
SYS "Wimp_SetCaretPosition", !a%, a%!4,,, -1, position%
ENDPROC


REM Test to see if an icon contains the caret.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to test, or -1 to test
REM				if a window contains the caret.
:
DEF FNicon_test_for_caret(window%, icon%)
SYS "Wimp_GetCaretPosition",,a%
IF icon%=-1 THEN a%!4 = -1
=((!a% = window%) AND (a%!4 = icon%))


REM Force an icon to be redrawn.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be redrawn.
:
DEF PROCicon_redraw(!a%, a%!4)
SYS "Wimp_GetIconState",,a%
SYS "Wimp_ForceRedraw", !a%, a%!8, a%!12, a%!16, a%!20
ENDPROC


REM Force an icon to be redrawn immediately via Wimp_UpdateWindow.
REM
REM \param window%		The handle of the window containing the icon.
REM \param icon%		The number of the icon to be redrawn.
:
DEF PROCicon_immediate_redraw(!a%, a%!4)
LOCAL more%

SYS "Wimp_GetIconState",,a%
a%!4 = !a%
SYS "Wimp_UpdateWindow",,a%+4 TO more%
WHILE more%
	SYS "Wimp_GetRectangle",,a% TO more%
ENDWHILE
ENDPROC


REM Create a standard Iconbar icon, returning the handle of the icon.
REM
REM \param window%		The window to create the icon in (-1 for the
REM				right-hand side of the iconbar, -2 for the
REM				left-hand side).
REM \param sprite$		The name of the sprite to use, from the Wimp Pool.
REM \return			The handle of the newly created icon.
:
DEF FNicon_create_standard_bar(!a%, sprite$)
LOCAL handle%

a%!4 = 0
a%!8 = 0
a%!12 = 68
a%!16 = 69
a%!20 = &3002
$(a% + 24) = sprite$
SYS "Wimp_CreateIcon",,a% TO handle%
=handle%

