/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for 
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #                                      
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Icon.h
    Author:  Copyright  1992, 1993, 1994 Jason Williams, Simon Truss
    Version: 1.15 (10 Nov 1995)
    Purpose: High-level icon handling routines
    History: 1.14 (?? Dec 1994)    - JW
             1.15 (10 Nov 1995) - ST - Added Desk_Icon_InsertText.
*/


#ifndef __Desk_Icon_h
#define __Desk_Icon_h

#ifdef __cplusplus
	extern "C" {
#endif


#ifndef __Desk_Wimp_h
#include "Desk.Wimp.h"
#endif

#ifndef __Desk_DragASpr_h
#include "Desk.DragASpr.h"
#endif


extern Desk_icon_handle Desk_Icon_BarIcon(const char *spritename, Desk_window_handle pos);
  /* 
   * sprite-only icon, with the "normal" default flags. If you want an
   * icon that is not this default, then create it yourself (it isn't hard!)
   *
   * If you wish to attach handlers/menus to the baricon, then remember
   * it's handle, and pass this to Desk_Event_Claim...
   * (Or wait for release 2 of DeskLib, which should have an Desk_Event_BarIcon)
   *
   * Pass in "spritename" -  the name of a sprite in the Wimp Sprite pool
   * and "pos", which should be Desk_iconbar_LEFT or Desk_iconbar_RIGHT
   * The correct size of the icon will be determined and used
   * Returns: The icon handle of the created icon
   */


extern Desk_icon_handle Desk_Icon_BarIconUser( const char *spritename, Desk_window_handle pos, 
                                     unsigned int *area);
  /*
   * Plonk a sprite from a USER sprite area on the icon bar
   * Returns icon handle.
   */
                                    


extern Desk_bool Desk_Icon_GetSelect(Desk_window_handle window, Desk_icon_handle icon);
  /*
   *  Returns Desk_bool_TRUE if the given icon is selected
   */


extern Desk_bool Desk_Icon_GetShade(Desk_window_handle window, Desk_icon_handle icon);
  /*
   *  Returns Desk_bool_TRUE if the given icon is shaded
   */


extern void Desk_Icon_SetSelect(Desk_window_handle window, Desk_icon_handle icon, int flag);
/* Equivalent in action to Desk_Icon_Select + Desk_Icon_Deselect: Pass in a flag to
 * set the new selected status of the icon (0 = deselect, 1 = select)
 */
 
extern void Desk_Icon_Select(Desk_window_handle window, Desk_icon_handle icon);
/* If the given icon is currently deselected, it is selected */

extern void Desk_Icon_Deselect(Desk_window_handle window, Desk_icon_handle icon);
/* If the given icon is currently selected, it is deselected */


extern void Desk_Icon_SetShade(Desk_window_handle window, Desk_icon_handle icon, int flag);
/* Equivalent in action to Desk_Icon_Shade + Desk_Icon_Unshade: Pass in a flag to
 * set the new shaded status of the icon (0 = unshaded, 1 = shaded)
 */

extern void Desk_Icon_Shade(Desk_window_handle window, Desk_icon_handle icon);
/*
 * if the icon is currently unshaded (active) it is shaded (made inactive)
 * This includes removing the caret from the icon.
 */

extern void Desk_Icon_Unshade(Desk_window_handle window, Desk_icon_handle icon);
/* if the icon is currently shaded (inactive) it is unshaded (made active) */


extern void Desk_Icon_SetForeColour(Desk_window_handle window, Desk_icon_handle icon,
                               int wimpcolour);
/*  Sets an icon's foreground colour to the given WIMP colour (in range 0..15).
 *  NOTE that this is a simple function which does not currently support
 *  outline font icons (in fact, it'll corrupt their font handle and cause
 *  untold grief)
 */

extern void Desk_Icon_SetBackColour(Desk_window_handle window, Desk_icon_handle icon,
                               int wimpcolour);
/*  Sets an icon's background colour to the given WIMP colour (in range 0..15).
 *  NOTE that this is a simple function which does not currently support
 *  outline font icons (in fact, it'll corrupt their font handle and cause
 *  untold grief)
 */


extern void Desk_Icon_ForceWindowRedraw(Desk_window_handle window, Desk_icon_handle icon);
/*  Force Redraws the area of WINDOW surrounding the icon, *including*
 *  the 3-d border (validation string "b<bordertype>")
 */

#define Desk_Icon_ForceRedraw(wind, icon) Desk_Wimp_SetIconState(wind, icon, 0, 0);
        /* Forces the WIMP to redraw (just) the icon */



extern void Desk_Icon_SetCaret(Desk_window_handle window, Desk_icon_handle icon);
/*
 * This routine sets the caret within the requested icon. It places the
 * caret at the (righthand) end of the text in the icon. If the icon is not
 * a text icon, then the function returns quietly
 */

extern void Desk_Icon_LoseCaret(Desk_window_handle window, Desk_icon_handle icon);
/* Desk_Icon_LoseCaret
 * This routine ensures that the caret is *not* contained within the
 * designated icon. Only sets a new position if the icon currently contains
 *  the caret.
 */



extern void Desk_Icon_SetInteger(Desk_window_handle w, Desk_icon_handle i, int value);
/*
 * Sets the given icon's text to hold the number in "value". (and redraws icon)
 * If the number is too long (too many digits) it will be truncated to fit.
 * If unable to set the text (incorrect icon type), it returns quietly
 */

extern void Desk_Icon_SetDouble(Desk_window_handle w, Desk_icon_handle i,
                           double value, int decimalplaces);
/*
 * Sets the given icon's text to hold the number in "value". (and redraws icon)
 * Only the first "decimalplaces" digits after the decimal point are
 * printed. If the number is too long (too many digits) it will be truncated
 * to fit. This may affect the accuracy or actual value of the number.
 * If unable to set the text (incorrect icon type), it returns quietly
 */

extern void Desk_Icon_SetText(Desk_window_handle w, Desk_icon_handle i, char *text);
/*
 * Copies the text string into the icon's indirected string buffer (and redraws)
 * If unable to set the text (incorrect icon type), it returns quietly
 * If text passed in is a NULL pointer, sets icon text to " "
 */

extern void Desk_Icon_SetTextRJ(Desk_window_handle w, Desk_icon_handle i, char *text);
/*
 * Copies the text string into the icon's indirected string buffer (and redraws)
 * This text is "right justified", meaning that if the text doesn't fit
 * into the available buffer space, it is truncated at the *LEFT*-hand side,
 * and preceded by a '...' (ellipsis) character.
 * If unable to set the text (incorrect icon type), it returns quietly
 * If text passed in is a NULL pointer, sets icon text to '\0'
 */


extern void Desk_Icon_printf(Desk_window_handle window, Desk_icon_handle icon,
                        const char *format, ...);
/* 
 * Exactly the same as sprintf, but instead of passing in a string into which
 * the result is written, you pass in the window+icon identifier of an
 * indirected icon. (Anything other than an indirected icon will return
 * quietly with NO effect)
 * e.g Desk_Icon_printf(window, 5, "%d bytes copied", current);
 */



extern double Desk_Icon_GetDouble(Desk_window_handle w, Desk_icon_handle i);
/*
 * Gets the given icon's text and returns it in the form of a "double"
 * floating-point value. 0 will be returned from any error/invalid text
 */

extern int Desk_Icon_GetInteger(Desk_window_handle w, Desk_icon_handle i);
/*
 * Gets the given icon's text and returns it in the form of an integer
 * numeric value. 0 will be returned from any error/invalid text
 */

extern void Desk_Icon_GetText(Desk_window_handle w, Desk_icon_handle i, char *text);
/*
 * Copies the text string from the icon (sprite name, text, or indirected)
 * into the array pointed to by "text"
 * Note that the array pointed to by "text" must be big enough to hold the
 * resulting string, so the minimum sizes are:
 *  If non-indirected (or a sprite), 12 characters
 *  If indirected text, the indirected size of the icon.
 */



extern char *Desk_Icon_GetTextPtr(Desk_window_handle, Desk_icon_handle);
/*    
    Inputs:   window, icon - handle pair of the icon to examine.
    Returns:  Pointer to the *actual* indirected text buffer used for the
              given icon.  If the icon is not indirected text, then you will
              get garbage back.
    Purpose:  Get a pointer to the indirected text buffer for this icon, so
              you can read/change it.
*/




#define Desk_Icon_SetFlags(window, icon, flags, set) \
  Desk_Wimp_SetIconState((window), (icon), ((set) ? (flags) : 0), (flags))
/*
Use like:
  Desk_os_error *Desk_Icon_SetFlags(Desk_window_handle window, 
                          Desk_icon_handle icon, 
                          int flags, 
                          Desk_bool set);
    
  Inputs:   window, icon - window and icon handle pair of icon to change.
            flags - bitfield specifying the bits to change.
            set - if Desk_bool_TRUE, all the flags defined by 'flags' will be set to
                  1, otherwise they will all be set to 0.
  Returns:  Usual RISC OS error block.
  Purpose:  Neat interface to the Desk_Wimp_SetIconState SWI.
  Errors:   As for Desk_Wimp_SetIconState()
*/


#define Desk_Icon_SetFgCol(w, i, col) \
Desk_Wimp_SetIconState((w), (i), (col) * Desk_icon_FORECOLOUR, 0xF * Desk_icon_FORECOLOUR)
/*
Use like:
  Desk_os_error *Desk_Icon_SetFgCol(Desk_window_handle window, Desk_icon_handle icon, int col) 
    
  Inputs:   window, icon - handle pair to identify the icon to change.
            col - the new foreground colour to apply to the icon.
  Returns:  Standard RISC OS error block.
  Purpose:  Macro to allow simple call to change the foreground colour
            of an icon (via the Desk_Wimp_SetIconState SWI).
  SeeAlso:  Desk_Icon_SetBgCol()
*/



#define Desk_Icon_SetBgCol(w, i, col) \
Desk_Wimp_SetIconState((w), (i), \
                (unsigned) (col) * (unsigned) Desk_icon_BACKCOLOUR, \
                (unsigned) 0xF * (unsigned) Desk_icon_BACKCOLOUR)
/*
Use like:
  Desk_os_error *Desk_Icon_SetBgCol( Desk_window_handle window, Desk_icon_handle icon, int col) 
    
  Inputs:   window, icon - handle pair to identify the icon to change.
            col - the new background colour to apply to the icon.
  Returns:  Standard RISC OS error block.
  Purpose:  Macro to allow simple call to change the background colour
            of an icon (via the Desk_Wimp_SetIconState SWI).
  SeeAlso:  Desk_Icon_SetFgCol()
*/
                

extern void Desk_Icon_ShadeGroup(Desk_window_handle window, 
                            Desk_icon_handle icons[], 
                            Desk_bool shade);
/*    
    Inputs:   window - the window that contains the icons to be changed.
              icons - array of icon handles that specify the icons to change.
                      The array should be terminated with -1.
              shade - Desk_bool_TRUE to shade the icons, Desk_bool_FALSE to unshade them.
    Purpose:  Shade a group of icons as defined by an -1 terminated array of
              icon handles.
    SeeAlso:  Desk_Icon_SelectGroup()
*/



extern void Desk_Icon_SelectGroup(Desk_window_handle window, 
                             Desk_icon_handle icons[], 
                             Desk_bool select);
/*    
    Inputs:   window - the window that contains the icons to be changed.
              icons - array of icon handles that specify the icons to change.
                      The array should be terminated with -1.
              select - Desk_bool_TRUE to select the icons, Desk_bool_FALSE to unselect them.
    Purpose:  Select or unselect a group of icons, as defined by an -1 
              terminated array of icon handles.
    SeeAlso:  Desk_Icon_ShadeGroup()
*/




extern int Desk_Icon_GetFgCol(const Desk_icon_block *icon);
/*
    int Desk_Icon_GetFgCol(Desk_icon_block *icon);
    
    Inputs:   icon - pointer to the icon info block that the colour should
                     be extracted.  This copes with anti-aliased icons.
    Returns:  The foreground colour of the described icon.
    Purpose:  Extract the foreground colour of an icon, coping with all the
              special cases.
*/


extern int Desk_Icon_GetBgCol(const Desk_icon_block *icon);
/*
    int Desk_Icon_GetBgCol(Desk_icon_block *icon);
    
    Inputs:   icon - pointer to the icon info block that the colour should
                     be extracted.  This copes with anti-aliased icons.
    Returns:  The background colour of the described icon.
    Purpose:  Extract the background colour of an icon, coping with all the
              special cases.
*/




extern void Desk_Icon_SetRadios(Desk_window_handle window,
                           Desk_icon_handle first, Desk_icon_handle last,
                           Desk_icon_handle onradio);
/*
 * Pass in a group of icons (specified by lowest-numbered icon and
 * highest-numbered icon), and the icon from this group that you want
 * selected. All icons except the one you want selected will be deselected.
 */

extern int Desk_Icon_WhichRadio(Desk_window_handle window,
                           Desk_icon_handle first, Desk_icon_handle last);
/*
 * This function accepts parameters for the first (lowest numbered) and
 * last (highest numnbered) in a group of icons (generally a group of radio
 * buttons). It returns the icon number of the first icon it finds within
 * this range which is selected (or "last" if none are selected).
 * Use it to find which of a group of radios is selected.
 */

extern int Desk_Icon_WhichRadioInEsg(Desk_window_handle wh, int esg);
/*
 * Basically the same as Desk_Icon_WhichRadio, but specifies the radio-group
 * by matching all icons with the given ESG, rather than having to have
 * a sequential block of icon numbers.
 */


extern void Desk_Icon_ClickWait(int waittime);
/*
 * Waits for the given number of centiseconds.
 * This is a MULTITASKING wait - although your program will do nothing,
 * the rest of the desktop will continue to run.
 * The wait is aborted after the given time, or as soon as an event is
 * received. If an attempt is made to re-enter ClickWait(), it will return
 * immediately (i.e. if a click event causes ClickWait to ba called, then
 * a second click while "waiting" from the first click will have no effect.
 */



extern void Desk_Icon_StartDrag(Desk_window_handle window, Desk_icon_handle icon);
/*
 * Starts a drag operation based on the given icon.
 * This is mainly used in "save as" windows to start drags of the file icon
 * when it is clicked on, but may be useful elsewhere.
 *
 * This call DOES NOT use DragASprite
 */


#define Desk_Icon_StartSolidDrag Desk_DragASprite_DragIcon
/*
 * Starts a drag operation based on the given icon, using DragASpr if available
 *   extern void Desk_Icon_StartSolidDrag(Desk_window_handle window, Desk_icon_handle icon);
 */


extern void Desk_Icon_DisposeIndData(Desk_icon_data *data, Desk_icon_flags flags);
/*
 * This will free any indirected data for this icon. It uses free(), so
 * obviously expects that malloc() was used to get the memory in the first
 * place, so make sure this is the case if you use this function.
 */



extern void Desk_Icon_FileIcon(Desk_window_handle window, Desk_icon_handle icon, int filetype);
/*
    Inputs:   window   - the window containing the icon to change.
              icon     - handle of the icon to change.
              filetype - desired filetype sprite to display.
    Purpose:  Changes an icon in a window to display the correct filetype
              sprite for the given filetype number.
              Requires that the specified icon is an indirected text-only
              icon with enough room in the text buffer to hold the sprite
              name.
              This function converts it to an indirected sprite-only icon,
              and fills in the sprite name and area.
             
              It does not check to make sure that the sprite corresponding
              to this filetype exists in the Wimp sprite pool - the caller
              should ensure that this is the case.
*/


extern void Desk_Icon_ScreenPos(Desk_window_handle window,
                           Desk_icon_handle icon,
                           Desk_wimp_rect *rect);
/*
    Inputs:   window   - the window containing the icon to examine.
              icon     - handle of the icon to examine.
    Outputs:  rect     - the screen coordinates of the icon.
    Purpose:  Gets the coordinate of an icon, and converts them into
              screen coordinates.
*/



/* =========================================================================
 * Special high-level icon functions:
 *   Slider icons: See "DeskLib.Libraries.Icon.c.Slider" for details
 */

extern int Desk_Icon_SetSlider(Desk_window_handle window,
                          Desk_icon_handle baseicon, Desk_icon_handle slidericon,
                          int sliderpos);
/* Sets a slider icon-pair to the specified position (specify as a
 * percentage). Values < 0 and > 1000 are clipped, and the value to which the
 * slider has been set is returned.
 */

extern int Desk_Icon_UpdateSlider(Desk_window_handle window,
                             Desk_icon_handle baseicon, Desk_icon_handle slidericon,
                             int lastpos);
/* (call on null events while slider being dragged)
 * Calculates a new slider percentage from the mouse pointer position.
 * If this differs from lastpos, the slider is updated (by recreating the
 * slidericon to the new length.
 * returns the new slider position percentage value.
 * NOTE: Slider update is achieved by DELETING and re-creating the slider
 * icon. This relies upon no icons of a lower icon handle having been deleted!
 */


extern int Desk_Icon_DragSlider(Desk_window_handle window,
                           Desk_icon_handle baseicon, Desk_icon_handle slidericon);
/* Initiates the drag operation on a slider. Call this when you get a click
 * in either baseicon or slidericon.
 * Returns the new percentage represented by the slider (remember this so
 * you can pass it in to Desk_Icon_UpdateSlider to save unnecessary (flickery)
 * update.)
 * NOTE: It is up to you to turn on NULL events and remember that
 * Desk_Icon_UpdateSlider must be called on each poll...
 * An alternative is to make the 2 slider icons use button type ALWAYS, and
 * check the mouse button state yourself to see whether a drag needs to be
 * started/continued...
 */

extern int Desk_Icon_ReadSlider(Desk_window_handle window,
                           Desk_icon_handle baseicon, Desk_icon_handle slidericon);
/* Given a slider icon-pair, returns a percentage representing the state */





typedef struct {
                Desk_window_handle window;
                Desk_icon_handle   texticon;
                Desk_icon_handle   incrementicon;
                Desk_icon_handle   decrementicon;
                Desk_bool          loop;
                unsigned int  step;
                int           min;
                int           max;
               } Desk_icon_incdecblock;
/*

  Purpose:  hold data for IncDec handlers
  Fields:   window         - handle of window holding icons
            texticon       - handle of text icon holding integer
            incrementicon  - handle of increment icon
            decrementicon  - handle of decrement icon
            loop           - Desk_bool_TRUE=loop beyond min & max limits
            step           - increment/decrement steps
            min            - lower limit
            max            - upper limit
  SeeAlso:  Desk_InitIcon_IncDecHandler
*/


extern Desk_icon_incdecblock *Desk_Icon_InitIncDecHandler(
                                           const Desk_window_handle window,
                                           const Desk_icon_handle   texticon,
                                           const Desk_icon_handle   incrementicon,
                                           const Desk_icon_handle   decrementicon,
                                           const Desk_bool          loop,
                                           const unsigned int  step,
                                           const int           min,
                                           const int           max,
                                           const int           start);
/*

  Purpose:  Claims handlers for clicks on Increment and Decrement Icons
            which increment decrement integer number in a text icon
  Inputs:   window         - handle of window
            texticon       - handle of text icon holding the integer number
                             which is to be incremented/decremented
            incrementicon  - handle of increment icon
                             click with select increments
                             click with adjust decrements
            decrementicon  - handle of decrement icon
                             click with select decrements
                             click with adjust increments
            loop           - Desk_bool_TRUE=integer loops past min & max limits
            step           - by how much integer is inc/decremented
            min            - minimum limit
            max            - maximum limit
            start          - starting integer
  Returns:  result of the claims to the click events on the icons
  SeeAlso:  Desk_Icon_ReleaseIncDecHandler
*/




extern Desk_bool Desk_Icon_ReleaseIncDecHandler(Desk_icon_incdecblock *incdecblock);
/*
  Purpose:  Release handlers for clicks on increment and decrement icons, &
              frees memory occupied by the data block pointed to by the d
  Inputs:   incdecblock - pointer to data block
  Returns:  result of releasing handlers
  SeeAlso:  Desk_Icon_InitIncDecHandler
*/



extern void Desk_Icon_AlterValidation(Desk_window_handle window, Desk_icon_handle icon,
                                 const char *newvalidation);
/*
  Purpose:  Alter the validation string of an icon. This causes a redraw of
            the icon after setting - useful for setting border types, etc
  Inputs:   window        - the window
            icon          - the icon
            newvalidation - the new validation string
  Returns:  -
  Notes:    If the validation string is already set to the given value,
            this function does nothing.
            WARNING - it is assumed that the new validation string will
            fit into the space used by the existing string - if this is
            not the case, you will overwrite and corrupt memory.
*/



extern Desk_bool Desk_Icon_ButtonIsHeld(void);
/*
 *  Returns Desk_bool_TRUE if a mouse button is held down.
 *
 *  Usage : With inc/dec type icons where auto-repeat is required for an
 *          icon using a 3D effect, with a button type 'Click'.
 *          It prevents the annoying repeated indent-outdent effect
 *          produced when using a button type 'Auto-Repeat' with a 3D
 *          icon.
 *  It currently returns Desk_bool_TRUE, even if the pointer is no longer over the
 *  icon, provided the button is still held down.
 */


extern void Desk_Icon_InsertText(Desk_window_handle w, Desk_icon_handle i, const char *text);
/*
 * Copies the text string into the icon's indirected string buffer (and redraws)
 * If unable to set the text (incorrect icon type),
 * it returns quietly. Text is inserted at caret if icon has the input focus
 * or to end of icon if it has no focus.
 * Uses full Error2 error-handling for wimp veneers and malloc.
 */


#ifdef __cplusplus
}
#endif


#endif
