File: n_svc_dwtoolbar.sru
Size: 81478
Date: Mon, 07 Apr 2008 21:31:42 +0200
$PBExportHeader$n_svc_dwtoolbar.sru
$PBExportComments$Datawindow based Toolbar service
forward
global type n_svc_dwtoolbar from n_svc_dw
end type
type str_toolbarcache from structure within n_svc_dwtoolbar
end type
end forward

type str_toolbarcache from structure
   boolean     largeicons
   str_dwtoolbarbutton     buttons[]
   string      toolbardwobject
   string      dwobject
   string      syntax
   long     width
   long     height
   long     themeid
end type

shared variables
str_toolbarcache sstr_cache[]
end variables

global type n_svc_dwtoolbar from n_svc_dw
boolean #pooled = true
end type
global n_svc_dwtoolbar n_svc_dwtoolbar

type prototypes
Function Boolean TrackMouseEvent ( ref trackmouseevent lpTrackMouseEvent ) Library 'user32.dll' alias for "TrackMouseEvent;Ansi"
Function ulong SetCapture(ulong hWnd) Library "USER32.DLL"
Function BOOLEAN ReleaseCapture() Library "USER32.DLL"
end prototypes

type variables
Protected:
//cache directory
CONSTANT string CACHE_DIRECTORY = "KodigoToolbarCache"
//metrics
CONSTANT integer SMALL_ICON = 16
CONSTANT integer LARGE_ICON = 24
CONSTANT integer BUTTON_GRADIENT_ADJUST = 4
CONSTANT integer TOOLBAR_GRADIENT_WIDTH = 1
CONSTANT integer TOOLBAR_GRADIENT_HEIGHT = 8 //current size + 8
CONSTANT integer BUTTON_GRADIENT_HOT_WIDTH = 1
CONSTANT integer BUTTON_GRADIENT_HOT_HEIGHT = 3 //current size + 4
CONSTANT integer BUTTON_Y = 5
CONSTANT integer TOOLBAR_X = 2
CONSTANT integer TOOLBAR_Y = 1
CONSTANT integer TOOLBAR_BORDER_X = 2
CONSTANT integer TOOLBAR_BORDER_Y = 2
CONSTANT integer TOOLBAR_BORDER_WIDTH = 2 //total buttons width + 2
CONSTANT integer TOOLBAR_BORDER_HEIGHT = 8 //current size + 11
CONSTANT integer BUTTON_BORDER_HOT_WIDTH = 6 //current size + 6
CONSTANT integer BUTTON_BORDER_HOT_HEIGHT = 6 //current size + 6
CONSTANT integer BUTTON_BORDER_HOT_X = 3 //current X - 3
CONSTANT integer BUTTON_BORDER_HOT_Y = 3 //current Y - 2
CONSTANT integer BUTTON_PAD = 2 //x space between buttons
CONSTANT integer ARROW_WIDTH = 8

//prefix-suffix
CONSTANT string BUTTON = "buttonid"
CONSTANT string GRIPPER = "gripper"
/* sample: buttonid001 */

CONSTANT string ICON = "_ico"
CONSTANT string BUTTON_BORDER_IMAGE = "_bbi"
CONSTANT string BUTTON_BORDER = "_bb1"
CONSTANT string BUTTON_BORDER2 = "_bb2" //used for dropdowns
CONSTANT string BUTTON_TEXT = "_txt"
CONSTANT string DROP_ARROW = "_arr"

CONSTANT string DIVIDER1 = "_dv1"
CONSTANT string DIVIDER2 = "_dv1"

//filename suffix
CONSTANT string F_STRIP_NORMAL = "sn"
CONSTANT string F_STRIP_END = "se"
CONSTANT string F_STRIP_HOT = "sh"
CONSTANT string F_STRIP_PRESSED = "sp"
CONSTANT string F_STRIP_CHECKED = "sc"
CONSTANT string F_NORMAL = "bn"
CONSTANT string F_HOT = "bh"
CONSTANT string F_DISABLED = "bd"
CONSTANT string F_PRESSED = "bp"
CONSTANT string F_CHECKED = "bc"
CONSTANT string F_EXT = ".bmp"

/*
 1 = dwobjname
 2 = filename
 3 = x
 4 = y
 5 = width
 6 = height
*/

CONSTANT string BITMAP_SYNTAX = 'CREATE bitmap(band=detail filename="{2}" x="{3}" y="{4}" height="{6}" width="{5}" border="0" name={1} visible="1")'
CONSTANT string BORDER_IMAGE_SYNTAX = 'CREATE bitmap(band=detail filename="{2}" x="{3}" y="{4}" height="{6}" width="{5}" border="0" name={1} visible="0")'

/*
 1 - name
 2 - color
 3 - x
 4 - y
 5 - width
 6 - height
 7 - tag (used for tooltips)
*/
CONSTANT string BORDER_SYNTAX = 'CREATE rectangle(band=detail x="{3}" y="{4}" height="{6}" width="{5}"  name={1} visible="1" brush.hatch="7" brush.color="671088641" pen.style="5" pen.width="5" pen.color="{2}"  background.mode="1" background.color="553648127" tag="{7}")'

/*
 1 - name
 2 - color
 3 - x
 4 - y
 5 - height
*/
CONSTANT string DIVIDER_SYNTAX = "CREATE text(band=foreground alignment='0' text='' border='0' color='{2}' x='{3}' y='{4}' height='{5}' width='4' html.valueishtml='0' name={1} visible='1' font.face='Marlett' font.height='-12' font.weight='400' font.family='0' font.pitch='2' font.charset='2' background.mode='0' background.color='{2}')"

/*
 1 - name
 2 - color
 3 - x
 4 - yes
 5 - width
 6 - height
*/
CONSTANT string TOOLBAR_BORDER_SYNTAX = 'CREATE roundrectangle(band=detail ellipseheight="16" ellipsewidth="18"x="{3}" y="{4}" height="{6}" width="{5}" name={1} visible="1" brush.hatch="7" brush.color="553648127" pen.style="0" pen.width="5" pen.color="{2}" background.mode="1" background.color="553648127")'

/*
 1 - name
 2 - text
 3 - x
 4 - y
 5 - width
 6 - height
 7 - color
*/
CONSTANT string TEXT_SYNTAX = 'CREATE text(band=detail alignment="0" text="{2}" border="0" color="{7}" x="{3}" y="{4}" height="{6}" width="{5}" html.valueishtml="0"  name={1} visible="1"  font.face="Tahoma" font.height="-8" font.weight="400"  font.family="2" font.pitch="2" font.charset="0" background.mode="1" background.color="553648127")'

/*
 1 - name
 2 - x
 3 - y
 4 - width
 5 - height
 6 - color
*/
CONSTANT string ARROW_SYNTAX = 'CREATE text(band=detail alignment="0" text="u" border="0" color="{6}" x="{2}" y="{3}" height="{5}" width="{4}" html.valueishtml="0"  name={1} visible="1"  font.face="Marlett" font.height="-8" font.weight="400"  font.family="0" font.pitch="2" font.charset="2" background.mode="1" background.color="553648127")'

/*
 1 - name
 2 - color
 3 - x
 4 - y
*/
CONSTANT string GRIPPER_SYNTAX = 'CREATE text(band=detail alignment="0" text="" border="0" color="33554432" x="{3}" y="{4}" height="8" width="9" html.valueishtml="0"  name={1} visible="1"  font.face="Tahoma" font.height="-12" font.weight="400"  font.family="2" font.pitch="2" font.charset="0" background.mode="2" background.color="{2}")'
end variables

forward prototypes
public function string of_makebuttonid (readonly string as_buttonid)
public function string of_getbuttonid (readonly string as_buttonid)
public function boolean of_isbutton (readonly string as_objname)
public function string of_makeimageindex (readonly integer ai_index)
public function integer of_indexfrombuttonid (readonly string as_buttonid, readonly str_dwtoolbarbutton astr_buttons[])
public function string of_getbuttonname (readonly string as_buttonid)
public function string of_getbuttonimagename (readonly string as_buttonid)
public function string of_getbuttonbordername (readonly string as_buttonid)
public function string of_getbuttonborder2name (readonly string as_buttonid)
public function string of_getbuttonarrowname (readonly string as_buttonid)
public subroutine of_makenormal (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[])
public subroutine of_makenormal (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly boolean ab_skipstates)
public function string of_getdivider1name (readonly string as_buttonid)
public function string of_getdivider2name (readonly string as_buttonid)
public function string of_getbuttontextname (readonly string as_buttonid)
public function boolean of_isbuttonhot (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar)
public function boolean of_isbuttonnormal (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar)
public function boolean of_isbuttonpressed (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[])
public subroutine of_makepressed (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[])
public subroutine of_dwmousemove (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[], integer ai_x, integer ai_y, readonly dwobject adwo, readonly boolean ab_mousedown, ref boolean ab_mousecaptured, ref string as_hotbutton)
public subroutine of_getdropcoordinates (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, ref integer ai_x, ref integer ai_y)
public subroutine of_buttonenable (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly boolean ab_enable)
public subroutine of_dwmousemove (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[], integer ai_x, integer ai_y, readonly string as_objname, readonly boolean ab_mousedown, ref boolean ab_mousecaptured, ref string as_hotbutton)
public subroutine of_buttoncheck (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly boolean ab_check)
public function boolean of_isbuttonchecked (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[])
public function boolean of_isbuttonenabled (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[])
public function string of_makestripfile (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, readonly integer ai_themeid, readonly string as_suffix, readonly string as_path, readonly long al_startcolor, readonly long al_endcolor, readonly integer ai_height)
public function string of_makeiconfile (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, readonly integer ai_themeid, readonly integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly string as_suffix, readonly string as_path, readonly long al_startcolor, readonly long al_endcolor, readonly boolean ab_disabled)
public subroutine of_addbuttons (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_dwtoolbar, ref str_dwtoolbarbutton astr_buttons[])
public subroutine of_buildtoolbar (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[], integer ai_startx, integer ai_starty, readonly boolean ab_gripper, readonly boolean ab_cachedefinition)
protected subroutine of_addtoolbarcache (readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[])
protected function integer of_getcacheindex (readonly u_dwtoolbar auo_toolbar)
public function boolean of_buildfromcache (readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[])
public function string of_gettoolbarcachedirectory ()
public subroutine of_flushcache ()
public function boolean of_isingripregion (readonly u_dwtoolbar auo, readonly long ax, readonly long ay)
public subroutine of_makehot (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[])
end prototypes

public function string of_makebuttonid (readonly string as_buttonid);//===========================================================================
// Function: of_Makebuttonid (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_tmp

ls_tmp = STRING(LONG(as_buttonid))

RETURN BUTTON + Fill("0", 3 - LEN(ls_tmp)) + ls_tmp
end function

public function string of_getbuttonid (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttonid (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_tmp
long ll_pos

ll_pos = POS(as_buttonid, BUTTON)
ls_tmp = MID(as_buttonid, ll_pos, LEN(BUTTON) + 3)

RETURN ls_tmp
end function

public function boolean of_isbutton (readonly string as_objname);//===========================================================================
// Function: of_Isbutton (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_objname
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long ll

ll = POS(as_objname, BUTTON)
IF ll <= 0 THEN RETURN FALSE

IF POS(as_objname, DIVIDER1) > 0 OR &
   POS(as_objname, DIVIDER1) > 0 THEN RETURN FALSE

RETURN TRUE
end function

public function string of_makeimageindex (readonly integer ai_index);//===========================================================================
// Function: of_Makeimageindex (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly Integer ai_index
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_tmp

ls_tmp = STRING(ai_index)

RETURN BUTTON + Fill("0", 3 - LEN(ls_tmp)) + ls_tmp
end function

public function integer of_indexfrombuttonid (readonly string as_buttonid, readonly str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Indexfrombuttonid (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//  readonly str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: Integer
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long ll_count, n

ll_count = UPPERBOUND(astr_buttons)
FOR n = 1 to ll_count
   IF astr_buttons[n].ButtonID = as_buttonid THEN RETURN n
NEXT

RETURN CRet.FAILURE
end function

public function string of_getbuttonname (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttonname (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + ICON
end function

public function string of_getbuttonimagename (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttonimagename (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + BUTTON_BORDER_IMAGE
end function

public function string of_getbuttonbordername (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttonbordername (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + BUTTON_BORDER
end function

public function string of_getbuttonborder2name (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttonborder2name (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + BUTTON_BORDER2
end function

public function string of_getbuttonarrowname (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttonarrowname (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + DROP_ARROW
end function

public subroutine of_makenormal (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Makenormal (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  value Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
of_MakeNormal(auo_toolbar, as_buttonid, ai_index, astr_buttons, FALSE)
end subroutine

public subroutine of_makenormal (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly boolean ab_skipstates);//===========================================================================
// Function: of_Makenormal (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  value Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//  readonly Boolean ab_skipstates
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_mod, ls_objname

IF of_IsButtonNormal(as_buttonid, auo_toolbar) THEN RETURN

IF ab_skipstates THEN
   IF astr_buttons[ai_index].Divider THEN RETURN
   IF NOT astr_buttons[ai_index].Visible THEN RETURN
   IF NOT astr_buttons[ai_index].Enabled THEN RETURN
   IF astr_buttons[ai_index].Checked THEN
      of_ButtonCheck(auo_toolbar, as_buttonid, ai_index, astr_buttons, TRUE)
      RETURN
   END IF
END IF

//icon
ls_objname = of_GetButtonName(as_buttonid)
ls_mod = ls_objname + ".FileName='" + astr_buttons[ai_index].normalimagefilename + "' "
//border image
ls_objname = of_GetButtonImageName(as_buttonid)
ls_mod += ls_objname + ".Visible=0 "
//border image
ls_objname = of_GetButtonBorderName(as_buttonid)
ls_mod += ls_objname + ".Pen.Style='5'"
IF astr_buttons[ai_index].DropDown AND NOT astr_buttons[ai_index].DropWhole THEN
   ls_objname = of_GetButtonBorder2Name(as_buttonid)
   ls_mod += ls_objname + ".Pen.Style='5'"
END IF

auo_toolbar.dw_1.Modify(ls_mod)
end subroutine

public function string of_getdivider1name (readonly string as_buttonid);//===========================================================================
// Function: of_Getdivider1name (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + DIVIDER1
end function

public function string of_getdivider2name (readonly string as_buttonid);//===========================================================================
// Function: of_Getdivider2name (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + DIVIDER2
end function

public function string of_getbuttontextname (readonly string as_buttonid);//===========================================================================
// Function: of_Getbuttontextname (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
RETURN as_buttonid + BUTTON_TEXT
end function

public function boolean of_isbuttonhot (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar);//===========================================================================
// Function: of_Isbuttonhot (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//  readonly u_dwtoolbar auo_toolbar
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls

ls = of_GetButtonBorderName(as_buttonid)
ls = lower(auo_toolbar.dw_1.Describe(ls + ".Pen.Style"))

CHOOSE CASE //lower(auo_toolbar.dw_1.Describe(ls + ".Visible"))
   CASE "1", "yes", "0"
      RETURN TRUE
   CASE ELSE
      RETURN FALSE
END CHOOSE
end function

public function boolean of_isbuttonnormal (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar);//===========================================================================
// Function: of_Isbuttonnormal (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//  readonly u_dwtoolbar auo_toolbar
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls

ls = of_GetButtonBorderName(as_buttonid)
//ls = lower(auo_toolbar.dw_1.Describe(ls + ".Visible"))
ls = lower(auo_toolbar.dw_1.Describe(ls + ".Pen.Style"))

CHOOSE CASE ls
   CASE "5"
      RETURN TRUE
// CASE "1", "yes"
//    RETURN FALSE
   CASE ELSE
      RETURN FALSE
END CHOOSE
end function

public function boolean of_isbuttonpressed (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Isbuttonpressed (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//  readonly u_dwtoolbar auo_toolbar
//  readonly str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls
long n

IF NOT of_IsButtonHot(as_buttonid, auo_toolbar) THEN RETURN FALSE

ls = of_GetButtonName(as_buttonid)

n = of_IndexFromButtonID(as_buttonid, astr_buttons)

//non-existing button
IF n = CRet.FAILURE THEN RETURN FALSE

CHOOSE CASE lower(auo_toolbar.dw_1.Describe(ls + ".Filename"))
   CASE lower(astr_buttons[n].pressedimagefilename)
      RETURN TRUE
   CASE ELSE
      RETURN FALSE
END CHOOSE
end function

public subroutine of_makepressed (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Makepressed (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  value Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long n, ll_count
string ls_mod, ls_objname

IF NOT astr_buttons[ai_index].Enabled THEN RETURN

//is it already hot?
IF NOT of_IsButtonPressed(as_buttonid, auo_toolbar, astr_buttons) THEN
   //icon
   ls_objname = of_GetButtonName(as_buttonid)
   ls_mod = ls_objname + ".FileName='" + astr_buttons[ai_index].pressedimagefilename + "' "
   //border image
   ls_objname = of_GetButtonImageName(as_buttonid)
   ls_mod += ls_objname + ".Visible=1 "
   ls_mod += ls_objname + ".FileName='" + astr_buttons[ai_index].pressedstripfilename + "' "
END IF

auo_toolbar.dw_1.Modify(ls_mod)
end subroutine

public subroutine of_dwmousemove (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[], integer ai_x, integer ai_y, readonly dwobject adwo, readonly boolean ab_mousedown, ref boolean ab_mousecaptured, ref string as_hotbutton);//===========================================================================
// Function: of_Dwmousemove (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  reference n_svc_mgr anv_svc
//  readonly u_dwtoolbar auo_toolbar
//  reference str_dwtoolbarbutton astr_buttons[]
//  value Integer ai_x
//  value Integer ai_y
//  readonly DWObject adwo
//  readonly Boolean ab_mousedown
//  reference Boolean ab_mousecaptured
//  reference String as_hotbutton
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_dwo

TRY
   IF NOT ISNULL(adwo) THEN 
      ls_dwo = STRING(adwo.Name)
   END IF
CATCH(RuntimeError ex)
END TRY

of_dwmousemove(anv_svc, &
               auo_toolbar, &
               astr_buttons, &
               ai_x, &
               ai_y, &
               ls_dwo, &
               ab_mousedown, &
               ab_mousecaptured, &
               as_hotbutton)
end subroutine

public subroutine of_getdropcoordinates (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, ref integer ai_x, ref integer ai_y);//===========================================================================
// Function: of_Getdropcoordinates (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  reference Integer ai_x
//  reference Integer ai_y
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls
n_svc_mgr lnv_svc
n_svc_win32 lnv_win32
rect rc

ls = of_Getbuttonbordername(as_buttonid)
ai_x = INTEGER(auo_toolbar.dw_1.Describe(ls + ".X"))
ai_y = INTEGER(auo_toolbar.dw_1.Describe(ls + ".Y"))
ai_y += INTEGER(auo_toolbar.dw_1.Describe(ls + ".Height"))
end subroutine

public subroutine of_buttonenable (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly boolean ab_enable);//===========================================================================
// Function: of_Buttonenable (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  value Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//  readonly Boolean ab_enable
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long n, ll_count, ll_color
string ls_mod, ls_objname, ls_filename

IF astr_buttons[ai_index].Enabled = ab_enable THEN RETURN

IF ab_enable THEN
   ls_filename = astr_buttons[ai_index].normalimagefilename
   ll_color = CColor.BUTTON_TEXT
ELSE
   ls_filename = astr_buttons[ai_index].disabledimagefilename
   ll_color = CColor.DISABLED_TEXT
   
   //create disabled image on demand
   IF NOT FileExists(ls_filename) THEN    
      n_svc_mgr lnv_svc
      n_svc_imagelist lnv_himl
      n_svc_theme lnv_t
      n_svc_files lnv_f
      str_theme Theme
      
      integer li_size
      ulong lul_himl
      
      lnv_svc.of_LoadSvc(lnv_himl, CSvc.IMAGELIST)
      lnv_svc.of_LoadSvc(lnv_t, CSvc.THEME)
      lnv_svc.of_LoadSvc(lnv_f, CSvc.FILES)
      
      Theme = lnv_t.of_GetTheme()
      lul_himl = auo_toolbar.of_GetImageList()
      IF auo_toolbar.#LargeIcons THEN
         li_size = LARGE_ICON
      ELSE
         li_size = SMALL_ICON
      END IF
      
      //fix filename entry
      IF ls_filename = CString.EMPTY THEN
         ls_filename = of_MakeImageIndex(astr_buttons[ai_index].ImageIndex)
         ls_filename = STRING(li_size) + STRING(Theme.ThemeID) + ls_filename + F_DISABLED + F_EXT
         ls_filename = lnv_f.of_combinepath(lnv_f.of_combinepath(lnv_f.of_GetTempPath(lnv_svc), CACHE_DIRECTORY), ls_filename)
      END IF

      lnv_himl.of_icontobitmapfile(lnv_svc, &
                                 lul_himl, &
                                 astr_buttons[ai_index].imageindex, &
                                 li_size, &
                                 Theme.ToolbarGradientStart, &
                                 Theme.ToolbarGradientEnd, &
                                 TRUE, &
                                 BUTTON_GRADIENT_ADJUST, &
                                 TRUE, &
                                 ls_filename)
   END IF
END IF

//make normal first
of_MakeNormal(auo_toolbar, as_buttonid, ai_index, astr_buttons, TRUE)
astr_buttons[ai_index].Enabled = ab_enable

IF astr_buttons[ai_index].DropDown THEN
   ls_objname = of_GetButtonArrowname(as_buttonid)
   ls_mod = " " + ls_objname + ".Color=" + STRING(ll_color)
   auo_toolbar.dw_1.Modify(ls_mod)
END IF

//icon
ls_objname = of_GetButtonName(as_buttonid)
ls_mod = ls_objname + ".FileName='" + ls_filename + "'"
ls_objname = of_GetButtonTextName(as_buttonid)
ls_mod += " " + ls_objname + ".Color=" + STRING(ll_color)

auo_toolbar.dw_1.SetRedraw(FALSE)
auo_toolbar.dw_1.Modify(ls_mod)
auo_toolbar.dw_1.SetRedraw(TRUE)
end subroutine

public subroutine of_dwmousemove (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[], integer ai_x, integer ai_y, readonly string as_objname, readonly boolean ab_mousedown, ref boolean ab_mousecaptured, ref string as_hotbutton);//===========================================================================
// Function: of_Dwmousemove (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  reference n_svc_mgr anv_svc
//  readonly u_dwtoolbar auo_toolbar
//  reference str_dwtoolbarbutton astr_buttons[]
//  value Integer ai_x
//  value Integer ai_y
//  readonly String as_objname
//  readonly Boolean ab_mousedown
//  reference Boolean ab_mousecaptured
//  reference String as_hotbutton
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_objname, ls_buttonid
long n, ll
boolean lb

ai_x = PixelsToUnits(ai_x, XPixelsToUnits!)
ai_y = PixelsToUnits(ai_y, YPixelsToUnits!)

IF as_hotbutton <> CString.EMPTY THEN 
   ls_objname = as_hotbutton
ELSE
   ls_objname = as_objname
   IF ISNULL(ls_objname) THEN ls_objname = CString.EMPTY
END IF

ls_buttonid = of_GetButtonid(ls_objname)
ll = of_IndexFromButtonid(ls_buttonid, astr_buttons)
IF ll > 0 THEN
   lb = astr_buttons[ll].Enabled
END IF

IF of_IsButton(ls_objname) AND lb THEN
   n = of_Indexfrombuttonid(ls_buttonid, astr_buttons)
   
   IF NOT ab_mousedown THEN
      IF ai_x >= astr_buttons[n].bounds.left AND &
         ai_x <= astr_buttons[n].bounds.left + astr_buttons[n].bounds.right AND &
         ai_y >= astr_buttons[n].bounds.top AND &
         ai_y <= astr_buttons[n].bounds.top + astr_buttons[n].bounds.bottom THEN
         
         IF NOT ab_MouseCaptured THEN
            SetCapture(Handle(auo_toolbar.dw_1))
            ab_MouseCaptured = TRUE
            as_hotbutton = ls_objname
         END IF
         
         IF ab_mousedown THEN
            of_MakePressed(auo_toolbar, ls_buttonid, n, astr_buttons)
         ELSE
            of_MakeHot(auo_toolbar, ls_buttonid, n, astr_buttons)
         END IF
      ELSE
         IF ab_MouseCaptured THEN
            ab_MouseCaptured = FALSE
            ReleaseCapture()
            as_hotbutton = CString.EMPTY
         END IF
         of_MakeNormal(auo_toolbar, ls_buttonid, n, astr_buttons, TRUE)
      END IF
   ELSE
      IF ai_x >= astr_buttons[n].bounds.left AND &
         ai_x <= astr_buttons[n].bounds.left + astr_buttons[n].bounds.right AND &
         ai_y >= astr_buttons[n].bounds.top AND &
         ai_y <= astr_buttons[n].bounds.top + astr_buttons[n].bounds.bottom THEN

         of_MakePressed(auo_toolbar, ls_buttonid, n, astr_buttons)
      ELSE
         of_MakeHot(auo_toolbar, ls_buttonid, n, astr_buttons)
      END IF
   END IF
ELSE
   long ll_count
   ll_count = UPPERBOUND(astr_buttons)
   FOR n = 1 to ll_count
      of_MakeNormal(auo_toolbar, astr_buttons[n].ButtonID, n, astr_buttons, TRUE)
   NEXT
   as_hotbutton = CString.EMPTY
   IF ab_MouseCaptured THEN 
      ReleaseCapture()
      ab_mousecaptured = FALSE
   END IF
END IF

IF of_IsInGripRegion(auo_toolbar, ai_x, ai_y) THEN
   auo_toolbar.dw_1.Modify("Datawindow.Pointer='Size!'")
ELSE
   auo_toolbar.dw_1.Modify("Datawindow.Pointer='Arrow!'")
END IF

//mouse capture bug-fix
IF ab_mousecaptured AND NOT KeyDown(KeyLeftButton!) THEN
   IF ai_x < 0 OR ai_x > auo_toolbar.width OR ai_y < 0 OR ai_y > auo_toolbar.height THEN
      //force release
      as_hotbutton = CString.EMPTY
      ab_mousecaptured = FALSE
      ReleaseCapture()
   END IF
END IF
end subroutine

public subroutine of_buttoncheck (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly boolean ab_check);//===========================================================================
// Function: of_Buttoncheck (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  value Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//  readonly Boolean ab_check
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long n, ll_count, ll_color
string ls_mod, ls_objname, ls_filename

IF astr_buttons[ai_index].Checked = ab_check THEN 
   IF NOT of_IsButtonHot(as_buttonid, auo_toolbar) THEN RETURN
END IF

astr_buttons[ai_index].Checked = ab_check

ls_objname = of_GetButtonName(as_buttonid)

IF ab_check THEN
   ls_filename = astr_buttons[ai_index].checkedimagefilename
ELSE
   ls_filename = astr_buttons[ai_index].normalimagefilename
END IF

//icon
IF auo_toolbar.dw_1.Describe(ls_objname + ".FileName") = ls_filename THEN RETURN

ls_mod = ls_objname + ".FileName='" + ls_filename + "'"
//border
ls_objname = of_GetButtonBorderName(as_buttonid)
IF ab_check THEN
   ls_mod += " " + ls_objname + ".Pen.Style=0"
ELSE
   ls_mod += " " + ls_objname + ".Pen.Style=5"
END IF
//background
ls_objname = of_GetButtonImageName(as_buttonid)
IF ab_check THEN
   ls_mod += " " + ls_objname + ".FileName='" + astr_buttons[ai_index].checkedstripfilename + "'"
   ls_mod += " " + ls_objname + ".Visible=1"
ELSE
   ls_mod += " " + ls_objname + ".FileName='" + astr_buttons[ai_index].hotstripfilename + "'"
   ls_mod += " " + ls_objname + ".Visible=0"
END IF
//dropdown
IF NOT astr_buttons[ai_index].DropWhole THEN
   ls_objname = of_GetButtonBorder2Name(as_buttonid)
   IF ab_check THEN
      ls_mod += " " + ls_objname + ".Pen.Style=0"
   ELSE
      ls_mod += " " + ls_objname + ".Pen.Style=5"
   END IF
END IF

//auo_toolbar.dw_1.SetRedraw(FALSE)
auo_toolbar.dw_1.Modify(ls_mod)
//auo_toolbar.dw_1.SetRedraw(TRUE)
end subroutine

public function boolean of_isbuttonchecked (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Isbuttonchecked (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//  readonly u_dwtoolbar auo_toolbar
//  readonly str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_id, ls
long n

ls_id = of_MakeButtonid(as_buttonid)
n = of_IndexFromButtonID(ls_id, astr_buttons)

//non-existing button
IF n = CRet.FAILURE THEN RETURN FALSE

RETURN astr_buttons[n].Checked
end function

public function boolean of_isbuttonenabled (readonly string as_buttonid, readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Isbuttonenabled (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly String as_buttonid
//  readonly u_dwtoolbar auo_toolbar
//  readonly str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls
long n

ls = of_GetButtonName(as_buttonid)
n = of_IndexFromButtonID(of_MakeButtonID(as_buttonid), astr_buttons)

//non-existing button
IF n = CRet.FAILURE THEN RETURN FALSE

RETURN astr_buttons[n].Enabled
end function

public function string of_makestripfile (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, readonly integer ai_themeid, readonly string as_suffix, readonly string as_path, readonly long al_startcolor, readonly long al_endcolor, readonly integer ai_height);//===========================================================================
// Function: of_Makestripfile (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  reference n_svc_mgr anv_svc
//  readonly u_dwtoolbar auo_toolbar
//  readonly Integer ai_themeid
//  readonly String as_suffix
//  readonly String as_path
//  readonly Long al_startcolor
//  readonly Long al_endcolor
//  readonly Integer ai_height in PBU
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_filename
integer li_size
n_svc_resource lnv_res
n_svc_files lnv_f

anv_svc.of_LoadSvc(lnv_res, CSvc.RESOURCE)
anv_svc.of_LoadSvc(lnv_f, CSvc.FILES)

IF auo_toolbar.#LargeIcons THEN
   li_size = 24
ELSE
   li_size = 16
END IF

ls_filename = STRING(li_size) + STRING(ai_themeid) + as_suffix + F_EXT
ls_filename = lnv_f.of_combinepath(as_path, ls_filename)
IF NOT FileExists(ls_filename) THEN
   lnv_res.of_makegradientstrip(anv_svc, &
                           al_startcolor, &
                           al_endcolor, &
                           TRUE, &
                           1, &
                           UnitsToPixels(ai_height, YUnitsToPixels!), &
                           ls_filename)

END IF

RETURN ls_filename
end function

public function string of_makeiconfile (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, readonly integer ai_themeid, readonly integer ai_index, ref str_dwtoolbarbutton astr_buttons[], readonly string as_suffix, readonly string as_path, readonly long al_startcolor, readonly long al_endcolor, readonly boolean ab_disabled);//===========================================================================
// Function: of_Makeiconfile (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  reference n_svc_mgr anv_svc
//  readonly u_dwtoolbar auo_toolbar
//  readonly Integer ai_themeid
//  readonly Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//  readonly String as_suffix
//  readonly String as_path
//  readonly Long al_startcolor
//  readonly Long al_endcolor
//  readonly Boolean ab_disabled
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_filename
integer li_size
n_svc_imagelist lnv_himl
n_svc_files lnv_f
ulong lul_himl

anv_svc.of_LoadSvc(lnv_himl, CSvc.IMAGELIST)
anv_svc.of_LoadSvc(lnv_f, CSvc.FILES)

lul_himl = auo_toolbar.of_GetImageList()

IF auo_toolbar.#LargeIcons THEN
   li_size = 24
ELSE
   li_size = 16
END IF

ls_filename = of_MakeImageIndex(astr_buttons[ai_index].ImageIndex)
ls_filename = STRING(li_size) + STRING(ai_themeid) + ls_filename + as_suffix + F_EXT
ls_filename = lnv_f.of_combinepath(as_path, ls_filename)
IF NOT FileExists(ls_filename) THEN    
   lnv_himl.of_icontobitmapfile(anv_svc, &
                        lul_himl, &
                        astr_buttons[ai_index].imageindex, &
                        li_size, &
                        al_startcolor, &
                        al_endcolor, &
                        TRUE, &
                        BUTTON_GRADIENT_ADJUST, &
                        ab_disabled, &
                        ls_filename)

END IF

RETURN ls_filename
end function

public subroutine of_addbuttons (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_dwtoolbar, ref str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Addbuttons (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  reference n_svc_mgr anv_svc
//  readonly u_dwtoolbar auo_dwtoolbar
//  reference str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
Datawindow ldw
Datastore lds

ldw = auo_dwtoolbar.dw_1
lds = auo_dwtoolbar.ids_buttons

IF NOT ISVALID(lds) THEN RETURN

n_svc_isempty lnv_check
n_svc_resource lnv_res

anv_svc.of_LoadSvc(lnv_res, CSvc.RESOURCE)
anv_svc.of_loadsvc(lnv_check, CSvc.ISEMPTY)

long ll_count, n
string ls_bitmap
w_tmp_resource lw
cresource lnvc
boolean lb

lds.SetSort("sort_order A")
lds.Sort()

OPEN(lw)
lnvc = CREATE cresource

ll_count = lds.RowCount()
FOR n = 1 to ll_count
   astr_buttons[n].id = lds.GetItemString(n, "id")
   astr_buttons[n].tooltip = lds.GetItemString(n, "tooltip")
   IF ISNULL(astr_buttons[n].tooltip) THEN astr_buttons[n].tooltip = CString.EMPTY
   astr_buttons[n].data = lds.GetItemString(n, "tagdata")
   astr_buttons[n].text = lds.GetItemString(n, "text")
   IF ISNULL(astr_buttons[n].text) THEN astr_buttons[n].text = CString.EMPTY
   lb = lds.GetItemNumber(n, "disabled") <> 1
   IF ISNULL(lb) THEN lb = FALSE
   astr_buttons[n].enabled = lb
   lb = lds.GetItemNumber(n, 'divider') = 1
   IF ISNULL(lb) THEN lb = FALSE
   astr_buttons[n].divider = lb
   lb = lds.GetItemNumber(n, 'dropdown') = 1
   IF ISNULL(lb) THEN lb = FALSE
   astr_buttons[n].dropdown = lb
   lb = lds.GetItemNumber(n, 'dropwhole') = 1
   IF ISNULL(lb) THEN lb = FALSE
   astr_buttons[n].dropwhole = lb
   astr_buttons[n].sortorder = lds.GetItemNumber(n, 'sort_order')
   astr_buttons[n].visible = TRUE
   
   //determine textwidth
   IF NOT lnv_check.of_IsEmpty(astr_buttons[n].text) THEN
      astr_buttons[n].textwidth = &
         lw.of_gettextwidth(astr_buttons[n].text) + &
            PixelsToUnits(BUTTON_BORDER_HOT_X * 2, XPixelsTounits!)
   END IF
   
   //image
   ls_bitmap = lds.GetItemString(n, 'image')
   IF lnv_check.of_Isempty(ls_bitmap) THEN
      astr_buttons[n].image = CString.EMPTY
      astr_buttons[n].imageindex = CRet.FAILURE
   ELSE
      IF ISNUMBER(ls_bitmap) THEN
         astr_buttons[n].imageindex = INTEGER(ls_bitmap) - 1
         astr_buttons[n].image = lnvc.BUTTONS[astr_buttons[n].imageindex]
      ELSE
         astr_buttons[n].image = ls_bitmap
         astr_buttons[n].imageindex = lnv_res.of_StandardImageIndexFromString(ls_bitmap) - 1
      END IF
   END IF
   
   //dwobject
   TRY
      astr_buttons[n].dwobjectname = lds.GetItemString(n, "dwobject")
      astr_buttons[n].dwobject = NOT lnv_check.of_IsEmpty(astr_buttons[n].dwobjectname)
   CATCH(Throwable t)
   END TRY
   
   //set buttonid
   astr_buttons[n].ButtonID = of_MakeButtonID(astr_buttons[n].id)
NEXT

CLOSE(lw)
DESTROY lnvc
end subroutine

public subroutine of_buildtoolbar (ref n_svc_mgr anv_svc, readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[], integer ai_startx, integer ai_starty, readonly boolean ab_gripper, readonly boolean ab_cachedefinition);//===========================================================================
// Function: of_Buildtoolbar (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  reference n_svc_mgr anv_svc
//  readonly u_dwtoolbar auo_toolbar
//  reference str_dwtoolbarbutton astr_buttons[]
//  value Integer ai_startx
//  value Integer ai_starty
//  readonly Boolean ab_gripper
//  readonly Boolean ab_cachedefinition
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long ll_count, n

ll_count = UPPERBOUND(astr_buttons)

IF ll_count <= 0 THEN RETURN

integer li_tmp, li_current_x, li_current_y, li_tmp_x, li_txt_x, li_tmp_w
string ls_tmp, ls_mod, ls_size, ls_themeid, ls_objname, ls_tag
integer li_size, li_size_x_pbu, li_size_y_pbu, li_text_y
ulong lul_himl
long ll_textcolor, ll_grippercount
rect lstr_bounds

//pad toolbar start
ai_startx += PixelsToUnits(1, XPixelsToUnits!)

li_current_x = ai_startx
li_current_y = ai_starty

//get imagelist
lul_himl = auo_toolbar.of_GetImageList()

//determine icon size
IF auo_toolbar.#LargeIcons THEN
   li_size = LARGE_ICON
   li_text_y = li_current_y + BUTTON_Y + 5
   ll_grippercount = 6
ELSE
   li_size = SMALL_ICON
   li_text_y = li_current_y + BUTTON_Y + 1
   ll_grippercount = 4
END IF
ls_size = STRING(li_size)
li_size_x_pbu = PixelsToUnits(li_size, XPixelsToUnits!)
li_size_y_pbu = PixelsToUnits(li_size, YPixelsToUnits!)
li_text_y = PixelsToUnits(li_text_y, YPixelsToUnits!)

n_svc_string lnv_str
n_svc_resource lnv_res
n_svc_imagelist lnv_himl
n_svc_theme lnv_t

string ls_path, ls_filename
string ls_disabledfilename, ls_hotfilename, ls_pressedfilename, ls_checkedfilename
string ls_toolbarstrip_filename, ls_buttonhotstrip_filename
string ls_buttoncheckedstrip_filename, ls_buttonpressedstrip_filename
string ls_toolbarendstrip_filename

//load services
anv_svc.of_LoadSvc(lnv_str, CSvc.STRING)
anv_svc.of_LoadSvc(lnv_res, CSvc.RESOURCE)
anv_svc.of_LoadSvc(lnv_himl, CSvc.IMAGELIST)
anv_svc.of_LoadSvc(lnv_t, CSvc.THEME)

//get theme
str_theme Theme
Theme = lnv_t.of_GetTheme()
ls_themeid = STRING(Theme.ThemeID)

//prepare path
ls_path = of_GetToolbarCacheDirectory()

//init metrics
integer li_toolbar_gradient_height, li_button_gradient_height
integer li_toolbar_border_height, li_toolbar_border_width
integer li_button_border_hot_width, li_button_border_hot_height, li_button_border_hot_y
integer li_button_pad, li_toolbar_x, li_toolbar_y
integer li_button_y
integer li_toolbar_border_x, li_toolbar_border_y
integer li_button_border_hot_x
integer li_arrow_width

li_toolbar_gradient_height = PixelsToUnits(li_size + TOOLBAR_GRADIENT_HEIGHT, YPixelsTounits!)
li_button_gradient_height = PixelsToUnits(li_size + BUTTON_GRADIENT_HOT_HEIGHT, YPixelsTounits!)
li_toolbar_border_height = PixelsToUnits(li_size + TOOLBAR_BORDER_HEIGHT, YPixelsTounits!)
li_toolbar_border_width = PixelsToUnits(TOOLBAR_BORDER_WIDTH, YPixelsTounits!)
li_button_border_hot_width = PixelsToUnits(li_size + BUTTON_BORDER_HOT_WIDTH, XPixelsTounits!)
li_button_border_hot_height = PixelsToUnits(li_size + BUTTON_BORDER_HOT_HEIGHT, YPixelsTounits!)
li_button_pad = PixelsToUnits(BUTTON_PAD, XPixelsTounits!)
li_toolbar_x = PixelsToUnits(TOOLBAR_X, XPixelsTounits!)
li_toolbar_y = PixelsToUnits(TOOLBAR_Y, YPixelsTounits!)
li_button_y = PixelsToUnits(BUTTON_Y, YPixelsTounits!)
li_toolbar_border_x = PixelsToUnits(TOOLBAR_BORDER_X, XPixelsTounits!)
li_toolbar_border_y = PixelsToUnits(TOOLBAR_BORDER_Y, YPixelsTounits!)
li_button_border_hot_x = PixelsToUnits(BUTTON_BORDER_HOT_X, XPixelsTounits!)
li_button_border_hot_y = li_button_y - PixelsToUnits(BUTTON_BORDER_HOT_Y, YPixelsTounits!)
li_arrow_width = PixelsToUnits(ARROW_WIDTH, XPixelsTounits!)

//create gradient strips for toolbar and hot border
//toolbar
//filename struc: 241sn.bmp (size=24, themeid=1, suffix=sn, extension=.bmp)
ls_toolbarstrip_filename = of_MakeStripFile(anv_svc, &
                     auo_toolbar, &
                     Theme.ThemeID, &
                     F_STRIP_NORMAL, &
                     ls_path, &
                     Theme.ToolbarGradientStart, &
                     Theme.ToolbarGradientEnd, &
                     li_toolbar_gradient_height)

//toolbar end 
ls_toolbarendstrip_filename= of_MakeStripFile(anv_svc, &
                     auo_toolbar, &
                     Theme.ThemeID, &
                     F_STRIP_END, &
                     ls_path, &
                     Theme.toolbarendgradientstart, &
                     Theme.toolbarendgradientend, &
                     li_toolbar_gradient_height)

//button strip hot
//filename struc: 241sh.bmp (size=24, themeid=1, suffix=sn, extension=.bmp)
ls_buttonhotstrip_filename = of_MakeStripFile(anv_svc, &
                     auo_toolbar, &
                     Theme.ThemeID, &
                     F_STRIP_HOT, &
                     ls_path, &
                     Theme.HotGradientStart, &
                     Theme.HotGradientEnd, &
                     li_button_border_hot_height)

//button strip pressed
//filename struc: 241sp.bmp (size=24, themeid=1, suffix=sp, extension=.bmp)
ls_buttonpressedstrip_filename = of_MakeStripFile(anv_svc, &
                     auo_toolbar, &
                     Theme.ThemeID, &
                     F_STRIP_PRESSED, &
                     ls_path, &
                     Theme.PressedGradientStart, &
                     Theme.PressedGradientEnd, &
                     li_button_border_hot_height)

//button strip checked
//filename struc: 241sc.bmp (size=24, themeid=1, suffix=sc, extension=.bmp)
ls_buttoncheckedstrip_filename = of_MakeStripFile(anv_svc, &
                     auo_toolbar, &
                     Theme.ThemeID, &
                     F_STRIP_CHECKED, &
                     ls_path, &
                     Theme.CheckedGradientStart, &
                     Theme.CheckedGradientEnd, &
                     li_button_border_hot_height)

IF ab_gripper THEN
   //build gripper
   long ll_gy
   ll_gy = PixelsToUnits(6, YPixelsToUnits!)
   //move x
   li_current_x += PixelsToUnits(5, XPixelsToUnits!)
   FOR n = 1 to ll_grippercount
      ls_objname = GRIPPER + STRING(n) + "1"
      
      /*
       1 = dwobjname
       2 = color
       3 = x
       4 = y
      */
      ls_mod += lnv_str.of_Format(GRIPPER_SYNTAX, &
                     {ls_objname, &
                      STRING(Theme.toolbargripper1), &
                      STRING(li_current_x), &
                      STRING(ll_gy)}) + CString.SPACE
   
      ls_objname = GRIPPER + STRING(n) + "2"
      ls_mod += lnv_str.of_Format(GRIPPER_SYNTAX, &
                     {ls_objname, &
                      STRING(Theme.toolbargripper2), &
                      STRING(li_current_x + PixelsToUnits(1, XPixelsToUnits!)), &
                      STRING(ll_gy + PixelsToUnits(1, YPixelsToUnits!))}) + CString.SPACE
                      
      ll_gy += PixelsToUnits(4, YPixelsToUnits!)
   NEXT
   //move x
   li_current_x += li_button_pad
END IF

//build buttons
FOR n = 1 to ll_count
   //move x
   li_current_x += li_button_pad
   //the border occupies BUTTON_BORDER_HOT_X
   //compute for actual image location
   li_tmp_x = li_current_x + (li_button_border_hot_x)
   //build button image file
   IF astr_buttons[n].imageindex <> Cret.FAILURE THEN
      //normal
      //filename struc: 2411001bn.bmp (size=24, themeid=1, imageindex=001 suffix=bn, extension=.bmp)
      ls_filename = of_MakeIconfile(anv_svc, &
                        auo_toolbar, &
                        Theme.ThemeID, &
                        n, &
                        astr_buttons, &
                        F_NORMAL, &
                        ls_path, &
                        Theme.ToolbarGradientStart, &
                        Theme.ToolbarGradientEnd, &
                        FALSE)
      
      //disabled
      IF NOT astr_buttons[n].Enabled THEN
         //filename struc: 241001bd.bmp (size=24, themeid=1, imageindex=001 suffix=bd, extension=.bmp)
         ls_disabledfilename = of_MakeIconfile(anv_svc, &
                           auo_toolbar, &
                           Theme.ThemeID, &
                           n, &
                           astr_buttons, &
                           F_DISABLED, &
                           ls_path, &
                           Theme.ToolbarGradientStart, &
                           Theme.ToolbarGradientEnd, &
                           TRUE)

      ELSE
         ls_disabledfilename = CString.EMPTY
      END IF
      //hot
      //filename struc: 241001bh.bmp (size=24, themeid=1, imageindex=001 suffix=bh, extension=.bmp)
      ls_hotfilename = of_MakeIconfile(anv_svc, &
                        auo_toolbar, &
                        Theme.ThemeID, &
                        n, &
                        astr_buttons, &
                        F_HOT, &
                        ls_path, &
                        Theme.HotGradientStart, &
                        Theme.HotGradientEnd, &
                        FALSE)

      //pressed
      //filename struc: 241001bp.bmp (size=24, themeid=1, imageindex=001 suffix=bp, extension=.bmp)
      ls_pressedfilename = of_MakeIconfile(anv_svc, &
                        auo_toolbar, &
                        Theme.ThemeID, &
                        n, &
                        astr_buttons, &
                        F_PRESSED, &
                        ls_path, &
                        Theme.PressedGradientStart, &
                        Theme.PressedGradientEnd, &
                        FALSE)


      //checked
      //filename struc: 241001bc.bmp (size=24, themeid=1, imageindex=001 suffix=bc, extension=.bmp)
      ls_checkedfilename = of_MakeIconfile(anv_svc, &
                        auo_toolbar, &
                        Theme.ThemeID, &
                        n, &
                        astr_buttons, &
                        F_CHECKED, &
                        ls_path, &
                        Theme.CheckedGradientStart, &
                        Theme.CheckedGradientEnd, &
                        FALSE)
      
      //store filenames
      astr_buttons[n].normalimagefilename = ls_filename
      astr_buttons[n].disabledimagefilename = ls_disabledfilename
      astr_buttons[n].hotimagefilename = ls_hotfilename
      astr_buttons[n].hotstripfilename = ls_buttonhotstrip_filename
      astr_buttons[n].pressedimagefilename = ls_pressedfilename
      astr_buttons[n].pressedstripfilename = ls_buttonpressedstrip_filename
      astr_buttons[n].checkedimagefilename = ls_checkedfilename
      astr_buttons[n].checkedstripfilename = ls_buttoncheckedstrip_filename
   END IF

   //create button if not divider
   IF NOT astr_buttons[n].Divider THEN
      //is it a dwobject?
      IF astr_buttons[n].dwobject THEN
         //move x
         li_current_x += li_button_pad
         //get the dwo bounds
         long llx, lly, llw, llh
         
         of_Getobjectrect(auo_toolbar.dw_1, &
                        astr_buttons[n].dwobjectname, &
                        llx, &
                        lly, &
                        llw, &
                        llh)
                        
         //modstring for position
         ls_mod += astr_buttons[n].dwobjectname + ".X='" + &
                     STRING(li_current_x) + "' "
         ls_mod += astr_buttons[n].dwobjectname + ".Y='" + &
                     STRING((li_button_border_hot_y + li_toolbar_border_height - llh) / 2)+ "' "

         li_current_x += llw + li_button_pad
      ELSE
         //button syntax first
         ls_objname = of_GetButtonName(astr_buttons[n].ButtonID)
         
         IF NOT astr_buttons[n].Enabled THEN
            ls_filename = ls_disabledfilename
         END IF
         
         /*
          1 = dwobjname
          2 = filename
          3 = x
          4 = y
          5 = width
          6 = height
         */
         ls_mod += lnv_str.of_Format(BITMAP_SYNTAX, &
                        {ls_objname, &
                         ls_filename, &
                         STRING(li_tmp_x), &
                         STRING(li_button_y), &
                         STRING(li_size_x_pbu), &
                         STRING(li_size_y_pbu)}) + CString.SPACE
         
         //set text color for text and arrow
         IF astr_buttons[n].Enabled THEN
            ll_textcolor = CColor.BUTTON_TEXT
         ELSE
            ll_textcolor = CColor.DISABLED_TEXT
         END IF
   
         //text syntax
         IF LEN(astr_buttons[n].Text) > 0 THEN
            ls_objname = of_GetButtonTextName(astr_buttons[n].ButtonID)
            
            //move x
            li_txt_x = li_current_x + li_button_border_hot_width
            
            /*
             1 = dwobjname
             2 - text
             3 - x
             4 - y
             5 - width
             6 - height
             7 - color
            */
            ls_mod += lnv_str.of_Format(TEXT_SYNTAX, &
                           {ls_objname, &
                            astr_buttons[n].Text, &
                            STRING(li_txt_x), &
                            STRING(li_text_y), &
                            STRING(astr_buttons[n].TextWidth), &
                            STRING(li_button_gradient_height - li_text_y), &
                            STRING(ll_textcolor)}) + CString.SPACE   
   
         END IF
   
         //drop arrow syntax
         IF astr_buttons[n].DropDown THEN
            ls_objname = of_GetButtonArrowName(astr_buttons[n].ButtonID)
            
            //move x
            li_txt_x = li_current_x + li_size_x_pbu + //PixelsTounits(1, XPixelsToUnits!)
            //has text
            IF LEN(astr_buttons[n].Text) > 0 THEN
               li_txt_x += astr_buttons[n].TextWidth
            END IF
            
            IF NOT astr_buttons[n].DropWhole THEN
               li_txt_x += (li_arrow_width) / 2
            END IF
            
            /*
             1 - name
             2 - x
             3 - y
             4 - width
             5 - height
             6 - color
            */
            
            ls_mod += lnv_str.of_Format(ARROW_SYNTAX, &
                           {ls_objname, &
                            STRING(li_txt_x + PixelsTounits(2, XPixelsToUnits!)), &
                            STRING(li_text_y + PixelsTounits(1, YPixelsToUnits!)), &
                            STRING(li_arrow_width), &
                            STRING(li_button_gradient_height - li_text_y), &
                            STRING(ll_textcolor)}) + CString.SPACE
         END IF
   
         //border image syntax
         ls_objname = of_GetButtonImageName(astr_buttons[n].ButtonID)
         
         //re-calc width based on text and arrow
         IF LEN(astr_buttons[n].Text) > 0 THEN
            li_tmp_w = li_button_border_hot_width + astr_buttons[n].TextWidth
         ELSE
            li_tmp_w = li_button_border_hot_width
         END IF
         
         IF astr_buttons[n].DropDown THEN
            li_tmp_w += li_arrow_width
            IF NOT astr_buttons[n].DropWhole THEN
               li_tmp_w += (li_arrow_width / 2)
            END IF
         END IF
         
         /*
          1 = dwobjname
          2 = filename
          3 = x
          4 = yes
          5 = width
          6 = height
         */
         ls_mod += lnv_str.of_Format(BORDER_IMAGE_SYNTAX, &
                        {ls_objname, &
                         ls_buttonhotstrip_filename, &
                         STRING(li_current_x), &
                         STRING(li_button_border_hot_y), &
                         STRING(li_tmp_w), &
                         STRING(li_button_border_hot_height)}) + CString.SPACE   
      
         //border syntax
         ls_objname = of_GetButtonBorderName(astr_buttons[n].ButtonID)
         
         /*
          1 = dwobjname
          2 = color
          3 = x
          4 = y
          5 = width
          6 = height
          7 - tag (used for tooltip)
         */
         
         IF astr_buttons[n].tooltip <> CString.EMPTY THEN
            ls_tag = CTooltip.KEY_TOOLTIP + "=" + astr_buttons[n].tooltip
         ELSE
            ls_tag = CString.EMPTY
         END IF
         
         ls_mod += lnv_str.of_Format(BORDER_SYNTAX, &
                        {ls_objname, &
                         STRING(Theme.ButtonBorder), &
                         STRING(li_current_x), &
                         STRING(li_button_border_hot_y), &
                         STRING(li_tmp_w), &
                         STRING(li_button_border_hot_height), &
                         ls_tag}) + CString.SPACE  
   
         //store bounds - bounds of button is based on border
         lstr_bounds.left = li_current_x
         lstr_bounds.right = li_tmp_w
         lstr_bounds.top = li_button_border_hot_y
         lstr_bounds.bottom = li_button_border_hot_height
         astr_buttons[n].bounds = lstr_bounds
         
   
         //if dropdown and not dropwhole, create another border for the arrow
         IF astr_buttons[n].DropDown AND NOT astr_buttons[n].DropWhole THEN
            ls_objname = of_GetButtonBorder2Name(astr_buttons[n].ButtonID)
            
            //calculate border2 X position
            li_tmp = li_arrow_width / 2
            li_tmp_x = li_current_x + li_tmp_w - (li_tmp * 3)
            
            
            /*
             1 = dwobjname
             2 = color
             3 = x
             4 = y
             5 = width
             6 = height
            */
            ls_mod += lnv_str.of_Format(BORDER_SYNTAX, &
                           {ls_objname, &
                            STRING(Theme.ButtonBorder), &
                            STRING(li_tmp_x), &
                            STRING(li_button_border_hot_y), &
                            STRING(li_arrow_width + li_tmp), &
                            STRING(li_button_border_hot_height)}) + CString.SPACE   
            
         END IF
   
         //update x
         li_current_x += li_tmp_w
      END IF
   ELSE
      //create divider
      ls_objname = of_GetDivider1Name(astr_buttons[n].ButtonID)
      /*
       1 - name
       2 - color
       3 - x
       4 - y
       5 - height
      */
      ls_mod += lnv_str.of_Format(DIVIDER_SYNTAX, &
                     {ls_objname, &
                      STRING(Theme.toolbarseparator1), &
                      STRING(li_current_x), &
                      STRING(li_button_y), &
                      STRING(li_size_y_pbu)}) + CString.SPACE  

      //increment 
      li_current_x += PixelsTounits(1, XPixelsToUnits!)
      
      //create divider
      ls_objname = of_GetDivider2Name(astr_buttons[n].ButtonID)
      /*
       1 - name
       2 - color
       3 - x
       4 - y
       5 - height
      */
      ls_mod += lnv_str.of_Format(DIVIDER_SYNTAX, &
                     {ls_objname, &
                      STRING(Theme.toolbarseparator2), &
                      STRING(li_current_x), &
                      STRING(li_button_y + PixelsToUnits(1, YPixelsToUnits!)), &
                      STRING(li_size_y_pbu)}) + CString.SPACE  

      //update x
//    li_current_x += li_button_pad
   END IF

NEXT

//create toolbar background
ls_objname = "toolbar"
ls_mod += lnv_str.of_Format(BITMAP_SYNTAX, &
                  {ls_objname, &
                   ls_toolbarstrip_filename, &
                   STRING(ai_startx + li_toolbar_x), &
                   STRING(ai_starty + li_toolbar_y), &
                   STRING(li_current_x + li_button_pad - li_toolbar_x), &
                   STRING(li_toolbar_gradient_height)}) + CString.SPACE 

//create toolbar end
ls_objname = "toolbar_end"
ls_mod += lnv_str.of_Format(BITMAP_SYNTAX, &
                  {ls_objname, &
                   ls_toolbarendstrip_filename, &
                   STRING(8 + li_current_x + li_button_pad - li_toolbar_x), &
                   STRING(ai_starty + li_toolbar_y), &
                   STRING(40), &
                   STRING(li_toolbar_gradient_height)}) + CString.SPACE 

//create toolbar border
ls_objname = "toolbarborder"
ls_mod += lnv_str.of_Format(TOOLBAR_BORDER_SYNTAX, &
                  {ls_objname, &
                   STRING(Theme.ToolbarBorder), &
                   STRING(ai_startx + li_toolbar_border_x), &
                   STRING(ai_starty + li_toolbar_border_y - 4), &
                   STRING(li_current_x + 39 + li_button_pad - li_toolbar_border_x), &
                   STRING(li_toolbar_border_height + 4)}) + CString.SPACE  

//detail height
ls_mod += "Datawindow.Detail.Height=200 "
//dw color
ls_mod += "Datawindow.Detail.Color=" + STRING(Theme.ToolbarBackground)

ls_mod = auo_toolbar.dw_1.Modify(ls_mod)
IF of_IsErrorString(ls_mod) THEN
   MessageBox("", ls_mod)
END IF

//set order of objects
//toolbar
auo_toolbar.dw_1.SetPosition("toolbar", "detail", TRUE)
//button image border
FOR n = 1 to ll_count
   auo_toolbar.dw_1.SetPosition(of_GetButtonImageName(astr_buttons[n].ButtonID), "detail", TRUE)
NEXT
//dividers
FOR n = 1 to ll_count
   IF NOT astr_buttons[n].Divider THEN CONTINUE
   auo_toolbar.dw_1.SetPosition(of_GetDivider2Name(astr_buttons[n].ButtonID), "detail", TRUE)
   auo_toolbar.dw_1.SetPosition(of_GetDivider1Name(astr_buttons[n].ButtonID), "detail", TRUE)
NEXT
//button
FOR n = 1 to ll_count
   auo_toolbar.dw_1.SetPosition(of_GetButtonName(astr_buttons[n].ButtonID), "detail", TRUE)
NEXT
//text and arrows
FOR n = 1 to ll_count
   auo_toolbar.dw_1.SetPosition(of_GetButtonTextName(astr_buttons[n].ButtonID), "detail", TRUE)
   auo_toolbar.dw_1.SetPosition(of_GetButtonArrowName(astr_buttons[n].ButtonID), "detail", TRUE)
NEXT
//dwobjects
FOR n = 1 to ll_count
   IF astr_buttons[n].dwobjectname = CString.EMPTY THEN CONTINUE
   auo_toolbar.dw_1.SetPosition(astr_buttons[n].dwobjectname, "detail", TRUE)
NEXT
//gripper
FOR n = 1 to ll_grippercount
   auo_toolbar.dw_1.SetPosition(GRIPPER + STRING(n) + "2", "detail", TRUE)
   auo_toolbar.dw_1.SetPosition(GRIPPER + STRING(n) + "1", "detail", TRUE)
NEXT
//button border on top of everything for tooltip support
FOR n = 1 to ll_count
   auo_toolbar.dw_1.SetPosition(of_GetButtonBorderName(astr_buttons[n].ButtonID), "detail", TRUE)
   auo_toolbar.dw_1.SetPosition(of_GetButtonBorder2Name(astr_buttons[n].ButtonID), "detail", TRUE)
NEXT

auo_toolbar.dw_1.SetPosition("toolbar_end", "detail", TRUE)

//set the toolbar height
auo_toolbar.of_SetDimensions( &
   /*width*/ li_current_x + 39 + li_button_pad - li_toolbar_border_x, &
   /*height*/ li_current_y + li_toolbar_border_y + li_toolbar_border_height)

IF ab_cachedefinition THEN
   of_AddToolbarcache(auo_toolbar, astr_buttons)
END IF

//auo_toolbar.Height = li_current_y + li_toolbar_border_y + &
//                   li_toolbar_border_height

end subroutine

protected subroutine of_addtoolbarcache (readonly u_dwtoolbar auo_toolbar, readonly str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Addtoolbarcache (protected )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long ll_index, ll_themeid

ll_index = of_GetCacheindex(auo_toolbar)

IF ll_index <> CRet.FAILURE THEN RETURN

ll_index = UPPERBOUND(sstr_cache) + 1
sstr_cache[ll_index].LargeIcons = auo_toolbar.#LargeIcons
sstr_cache[ll_index].buttons = astr_buttons
sstr_cache[ll_index].toolbardwobject = auo_toolbar.#ToolbarDataObject
sstr_cache[ll_index].dwobject = auo_toolbar.#DataObject
sstr_cache[ll_index].width = auo_toolbar.width
sstr_cache[ll_index].height = auo_toolbar.height
sstr_cache[ll_index].syntax = auo_toolbar.dw_1.Describe("Datawindow.Syntax")

ll_themeid = auo_toolbar.of_GetTheme().ThemeID

IF ll_themeid <= 0 THEN
   n_svc_mgr lnv_svc
   n_svc_theme lnv_t
   
   lnv_svc.of_LoadSvc(lnv_t, CSvc.THEME)
   ll_themeid = lnv_t.of_GetTheme().ThemeID
END IF

sstr_cache[ll_index].ThemeID = ll_themeid
end subroutine

protected function integer of_getcacheindex (readonly u_dwtoolbar auo_toolbar);//===========================================================================
// Function: of_Getcacheindex (protected )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//---------------------------------------------------------------------------
// Returns: Integer
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long ll_count, n
long ll_ret, ll_theme
n_svc_mgr lnv_svc
n_svc_theme lnv_t
str_theme lstr

ll_ret = CRet.FAILURE

lnv_svc.of_LoadSvc(lnv_t, CSvc.THEME)
lstr = lnv_t.of_GetTheme()

ll_count = UPPERBOUND(sstr_cache)
FOR n = 1 to ll_count
   IF auo_toolbar.#LargeIcons = sstr_cache[n].LargeIcons THEN
      IF auo_toolbar.#ToolbarDataObject = sstr_cache[n].ToolbarDWObject &
         AND auo_toolbar.#DataObject = sstr_cache[n].DWObject THEN

         //check theme
         ll_theme = auo_toolbar.of_GetTheme().ThemeID
         IF ll_theme <= 0 THEN
            ll_theme = lstr.ThemeID
         END IF
         
         IF sstr_cache[n].ThemeID <> ll_theme THEN CONTINUE
         
         ll_ret = n
         EXIT
      END IF
   END IF
NEXT

RETURN ll_ret
end function

public function boolean of_buildfromcache (readonly u_dwtoolbar auo_toolbar, ref str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Buildfromcache (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  reference str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: Boolean
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long ll_index
string ls_err

ll_index = of_GetCacheIndex(auo_toolbar)

IF ll_index = CRet.FAILURE THEN RETURN FALSE

astr_buttons = sstr_cache[ll_index].buttons
IF auo_toolbar.dw_1.Create(sstr_cache[ll_index].syntax, ls_err) = CRet.FAILURE THEN
// Messagebox("Error on Create Toolbar from Cache", ls_err, StopSign!)
   RETURN FALSE
END IF

auo_toolbar.dw_1.InsertRow(0)
auo_toolbar.of_SetDimensions(sstr_cache[ll_index].width, sstr_cache[ll_index].height)

RETURN TRUE
end function

public function string of_gettoolbarcachedirectory ();//===========================================================================
// Function: of_Gettoolbarcachedirectory (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  
//---------------------------------------------------------------------------
// Returns: String
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
string ls_path
n_svc_mgr lnv_svc
n_svc_files lnv_f

lnv_svc.of_LoadSvc(lnv_f, CSvc.FILES)

ls_path = lnv_f.of_GetTempPath(lnv_svc)
ls_path = lnv_f.of_Combinepath(ls_path, CACHE_DIRECTORY)
//create directory
IF NOT DirectoryExists(ls_path) THEN
   CreateDirectory(ls_path)
END IF

RETURN ls_path
end function

public subroutine of_flushcache ();//===========================================================================
// Function: of_Flushcache (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================

//flush toolbar cache and delete directory
str_toolbarcache lstr_empty[]

sstr_cache = lstr_empty

n_svc_mgr lnv_svc
n_svc_files lnv_f
string ls_path

ls_path = of_GetToolbarCacheDirectory()

lnv_svc.of_LoadSvc(lnv_f, CSvc.FILES)
lnv_f.of_DelTree(lnv_svc, ls_path)
end subroutine

public function boolean of_isingripregion (readonly u_dwtoolbar auo, readonly long ax, readonly long ay);long llminy, llmaxy
long llminx, llmaxx

llminy = 6
llminx = 6
llmaxx = 9

IF auo.#LargeIcons THEN
   llmaxy = llminy * 6
ELSE
   llmaxy = llminy * 4
END IF

//convert
llminx = PixelsToUnits(llminx, XPixelsToUnits!)
llmaxx = PixelsToUnits(llmaxx, XPixelsToUnits!)
llminy = PixelsToUnits(llminy, YPixelsToUnits!)
llmaxy = PixelsToUnits(llmaxy, YPixelsToUnits!)

boolean lb
lb = (ax >= llminx AND ax <= llmaxx) AND &
   (ay >= llminx AND ay <= llmaxy)
   
RETURN lb
end function

public subroutine of_makehot (readonly u_dwtoolbar auo_toolbar, readonly string as_buttonid, integer ai_index, ref str_dwtoolbarbutton astr_buttons[]);//===========================================================================
// Function: of_Makehot (public )
// Object: n_svc_dwtoolbar
//---------------------------------------------------------------------------
// Description:
// Note:
//---------------------------------------------------------------------------
// Parameters:
//  readonly u_dwtoolbar auo_toolbar
//  readonly String as_buttonid
//  value Integer ai_index
//  reference str_dwtoolbarbutton astr_buttons[]
//---------------------------------------------------------------------------
// Returns: (none)
//---------------------------------------------------------------------------
// Author: (Yeyi) Gabriel B. Abulencia
//===========================================================================
long n, ll_count
string ls_mod, ls_objname

IF NOT astr_buttons[ai_index].Enabled THEN RETURN

//is it already hot?
IF of_IsButtonNormal(as_buttonid, auo_toolbar) OR of_IsButtonPressed(as_buttonid, auo_toolbar, astr_buttons) OR astr_buttons[ai_index].Checked THEN
// IF NOT of_IsButtonHot(as_buttonid, auo_toolbar) THEN//OR NOT of_IsButtonPressed(as_buttonid, auo_toolbar, astr_buttons) THEN
   //icon
   ls_objname = of_GetButtonName(as_buttonid)
   ls_mod = ls_objname + ".FileName='" + astr_buttons[ai_index].hotimagefilename + "' "
   //border image
   ls_objname = of_GetButtonImageName(as_buttonid)
   ls_mod += ls_objname + ".Visible=1 "
   ls_mod += ls_objname + ".FileName='" + astr_buttons[ai_index].hotstripfilename + "' "
   //border
   ls_objname = of_GetButtonBorderName(as_buttonid)
   ls_mod += ls_objname + ".Pen.Style='0'"
   IF astr_buttons[ai_index].DropDown AND NOT astr_buttons[ai_index].DropWhole THEN
      ls_objname = of_GetButtonBorder2Name(as_buttonid)
      ls_mod += ls_objname + ".Pen.Style='0'"
   END IF
// END IF
   auo_toolbar.dw_1.Modify(ls_mod)
END IF

//make all other buttons normal
ll_count = UPPERBOUND(astr_buttons)
FOR n = 1 to ll_count
   IF n = ai_index THEN CONTINUE
   of_MakeNormal(auo_toolbar, astr_buttons[n].ButtonID, n, astr_buttons, TRUE)
NEXT


end subroutine

on n_svc_dwtoolbar.create
call super::create
end on

on n_svc_dwtoolbar.destroy
call super::destroy
end on