File: n_svc_resize.sru
Size: 11551
Date: Mon, 07 Apr 2008 21:31:25 +0200
$PBExportHeader$n_svc_resize.sru
$PBExportComments$Resize Service
forward
global type n_svc_resize from n_svc_base
end type
end forward

global type n_svc_resize from n_svc_base
end type
global n_svc_resize n_svc_resize

type variables
private:
CONSTANT long DROPDOWNHEIGHT = //86
CONSTANT string ANCHOR = "ANCHOR"
//CONSTANT long MINWIDTH = 240
end variables
forward prototypes
protected function long of_getcontrolreference (readonly string cls, readonly str_resize resize[])
protected function str_resize of_dock (ref dragobject ado, readonly integer docktype, readonly integer x, readonly integer y, readonly integer width, readonly integer height, readonly str_resize astr)
public subroutine of_resize (readonly powerobject apo, readonly string classname, ref str_resize resize[], readonly integer oldwidth, readonly integer oldheight, readonly integer newwidth, readonly integer newheight)
public subroutine of_initresize (ref n_svc_mgr anv_svc, powerobject apo, ref str_resize attrib[])
public subroutine of_initresize (ref n_svc_mgr anv_svc, readonly u_dw adw, ref str_resize attrib[])
public subroutine of_resize (u_dw adw, ref str_resize attrib[], readonly integer oldwidth, readonly integer oldheight, readonly integer newwidth, readonly integer newheight)
end prototypes

protected function long of_getcontrolreference (readonly string cls, readonly str_resize resize[]);long lc, n
n_svc_powerbuilder lnp
n_svc_mgr lnv_Svc

lnv_svc.of_LoadSvc(lnp, CSvc.Powerbuilder)

lc = UPPERBOUND(resize)

FOR n = 1 to lc
   IF resize[n].controlname = cls THEN 
      IF resize[n].control.Visible THEN 
         RETURN n
      ELSE
         IF resize[n].ignorevisible THEN RETURN n
      END IF
   END IF
NEXT
RETURN CRet.FAILURE
end function

protected function str_resize of_dock (ref dragobject ado, readonly integer docktype, readonly integer x, readonly integer y, readonly integer width, readonly integer height, readonly str_resize astr);long ll_h
boolean lb

//dropdown exception
IF astr.ancestor = CFbase.DropdownListBox OR astr.ancestor = CFbase.DropdownPictureListBox THEN
   ll_h = ado.height
   lb = TRUE
ELSE
   ll_h = height
END IF

CHOOSE CASE docktype
   CASE CDock.top
      IF ado.x <> x OR ado.Y <> y THEN ado.Move(x, y)
      IF ado.width <> width THEN ado.width = width
   CASE CDock.left //left
      IF ado.x <> x OR ado.Y <> y THEN ado.Move(x, y)
      IF ado.height <> ll_h THEN ado.height = ll_h
   CASE CDock.right
      ado.Move(width - ado.width, y)
      IF ado.height <> ll_h THEN ado.height = ll_h          
   CASE CDock.bottom
      IF ado.x <> x OR ado.Y <> ll_h - ado.height THEN ado.Move(x, ll_h - ado.height)
      IF ado.width <> width THEN ado.width = width
   CASE CDock.fill
      IF ado.x <> x OR ado.Y <> y THEN ado.Move(x, y)
      IF ado.width <> width OR ado.height <> ll_h THEN ado.Resize(width, ll_h)
END CHOOSE

astr.bounds.left = ado.X
astr.bounds.top = ado.Y
astr.bounds.right = ado.Width
//dropdown exception
IF lb THEN
   astr.bounds.bottom = DROPDOWNHEIGHT
ELSE
   astr.bounds.bottom = ado.Height
END IF

RETURN astr
end function

public subroutine of_resize (readonly powerobject apo, readonly string classname, ref str_resize resize[], readonly integer oldwidth, readonly integer oldheight, readonly integer newwidth, readonly integer newheight);long n, lc, c
long x, y, w, h, llt, llpw
rect lstr_rect
str_resize lstr
Boolean IS_WINDOW, lb
w_main lw
u_base_container lu

IF classname = CFbase.WindowMain THEN
   IS_WINDOW = TRUE
   lw = apo
ELSEIF classname = CFbase.UOContainer THEN
   lu = apo
ELSE
   RETURN
END IF

lc = UPPERBOUND(resize)

//workspace
IF IS_WINDOW THEN
   lstr_rect = lw.of_getworkspace()
ELSE
   lstr_rect = lu.of_getworkspace()
END IF

FOR n = 1 to lc
   //docked or not?
   IF resize[n].Dock THEN
      //check left
      c = resize[n].refleftindex
      IF c = 0 THEN 
         c = this.of_getcontrolreference(resize[n].refleft, resize)
         resize[n].refleftindex = c
      END IF
      IF c > 0 THEN
         x = resize[c].bounds.left + resize[c].bounds.right
      ELSE
         x = lstr_rect.left
      END IF
      //check top
      c = resize[n].reftopindex
      IF c = 0 THEN 
         c = this.of_getcontrolreference(resize[n].reftop, resize)
         resize[n].reftopindex = c
      END IF
      IF c > 0 THEN
         y = resize[c].bounds.top + resize[c].bounds.bottom
      ELSE
         y = lstr_rect.top
      END IF
      //check right
      c = resize[n].refrightindex
      IF c = 0 THEN 
         c = this.of_getcontrolreference(resize[n].refright, resize)
         resize[n].refrightindex = c
      END IF
      IF c > 0 THEN
         w = resize[c].bounds.left - x
      ELSE
         w = newwidth - x
      END IF
      //check bottom
      c = resize[n].refbottomindex
      IF c = 0 THEN 
         c = this.of_getcontrolreference(resize[n].refbottom, resize)
         resize[n].refbottomindex = c
      END IF
      IF c > 0 THEN
         h = resize[c].bounds.top - y
      ELSE
         h = newheight - y
      END IF      
      
      //adjust padding
      IF resize[n].dockpadleft <> 0 THEN
         x += resize[n].dockpadleft
         w -= resize[n].dockpadleft
      END IF
      
      IF resize[n].dockpadright <> 0 THEN
         w -= resize[n].dockpadright
      END IF
      
      IF resize[n].dockpadtop <> 0 THEN
         y += resize[n].dockpadtop
         h -= resize[n].dockpadtop
      END IF
      
      IF resize[n].dockpadbottom <> 0 THEN
         h -= resize[n].dockpadbottom
      END IF
      
      resize[n] = this.of_dock(resize[n].Control, resize[n].DockType, x, y, w, h, resize[n])
      
      CONTINUE    
   ELSE
      //init variables for anchor mode
      x = resize[n].bounds.left
      y = resize[n].bounds.top
      w = resize[n].bounds.right
      h = resize[n].bounds.bottom
      //dropdown exception
      IF resize[n].ancestor = CFbase.DropdownListBox OR resize[n].ancestor = CFbase.DropdownPictureListBox THEN
         h = resize[n].control.height
         lb = TRUE
      ELSE
         lb = FALSE
      END IF      

      IF resize[n].AnchorTop THEN y = resize[n].bounds.top
      IF resize[n].AnchorLeft THEN x = resize[n].bounds.left

      IF resize[n].AnchorRight THEN
         llt = newwidth - oldwidth 
         IF NOT resize[n].AnchorLeft THEN
               x += llt
         ELSE
               w += llt
         END IF
      END IF

      IF resize[n].AnchorBottom THEN
         llt = newheight - oldheight
         IF NOT resize[n].AnchorTop THEN
               y += llt
         ELSE
               h += llt
         END IF
      END IF   
      //resize and move only if changed to prevent flicker
      IF resize[n].Control.width <> w OR resize[n].Control.height <> h THEN 
         resize[n].Control.Resize(w, h)
      END IF
      IF resize[n].Control.X <> x OR resize[n].Control.Y <> y THEN resize[n].Control.Move(x, y)
   END IF
   //update attributes
   resize[n].bounds.left = x
   resize[n].bounds.top = y
   resize[n].bounds.right = w
   //dropdown exception
   IF lb THEN
      resize[n].bounds.bottom = DROPDOWNHEIGHT
   ELSE
      resize[n].bounds.bottom = h
   END IF
NEXT
end subroutine

public subroutine of_initresize (ref n_svc_mgr anv_svc, powerobject apo, ref str_resize attrib[]);long lc, n, c, lc2
str_resize lstre[], lstr, lstrt
Boolean lb
n_svc_powerbuilder lnp
WindowObject lwo[]
w_main lw_base
u_base_container lu_base
Boolean IS_WBASE
string ls_classname

//reset array
attrib = lstre
//load service
anv_svc.of_loadsvc(lnp, CSvc.POWERBUILDER)

TRY
   //check if supported parent object
   IF lnp.of_isdescendant(CFbase.WindowMain, apo.ClassDefinition) THEN
      //cast
      lw_base = apo
      lwo = lw_base.Control      
      IS_WBASE = TRUE
   ELSEIF lnp.of_isdescendant(CFbase.UOContainer, apo.ClassDefinition) THEN
      //cast
      lu_base = apo
      lwo = lu_base.Control
   ELSE
      RETURN
   END IF
CATCH (n_x_svc ex)
   // an exception occurred, exit
   RETURN
END TRY

lc = UPPERBOUND(lwo)

FOR n = 1 to lc

   IF IS_WBASE THEN
      //skip if mdi client
      IF lwo[n].TypeOf() = mdiclient! THEN CONTINUE
   END IF

   //ensure fc object
   IF NOT lnp.of_isfcobject(lwo[n]) THEN CONTINUE
   
   //increment index
   lstrt = lwo[n].DYNAMIC of_getresizeattrib()
   IF NOT lstrt.control.visible THEN
      TRY
         IF (NOT lnp.of_isdescendant(CFbase.Toolbar, lstrt.Control.ClassDefinition)) AND (NOT lnp.of_isdescendant(CFbase.Rebar, lstrt.Control.ClassDefinition)) THEN CONTINUE
         lstrt.ignorevisible = TRUE
      CATCH (throwable e)
         CONTINUE
      END TRY
   END IF
   IF lstrt.sizeorder < 0 THEN CONTINUE
   c ++
   
   attrib[c] = lstrt
NEXT

//sort by SizeOrder
lc = UPPERBOUND(attrib)
lc2 = lc - 1
FOR n = 1 TO lc
   lb = FALSE
   FOR c = 1 TO lc2
      IF attrib[c].SizeOrder > attrib[c + 1].SizeOrder THEN
         lb = TRUE
         lstr = attrib[c]
         attrib[c] = attrib[c + 1]
         attrib[c + 1] = lstr
      END IF
   NEXT
   IF NOT lb THEN EXIT
NEXT

//set control reference index
lc = UPPERBOUND(attrib)
FOR n = 1 to lc
   attrib[n].reftopindex = this.of_getcontrolreference(attrib[n].reftop, attrib)
   attrib[n].refleftindex = this.of_getcontrolreference(attrib[n].refleft, attrib)
   attrib[n].refrightindex = this.of_getcontrolreference(attrib[n].refright, attrib)
   attrib[n].refbottomindex = this.of_getcontrolreference(attrib[n].refbottom, attrib)
NEXT
end subroutine

public subroutine of_initresize (ref n_svc_mgr anv_svc, readonly u_dw adw, ref str_resize attrib[]);n_svc_dw lnd
n_svc_isempty lnc
n_svc_string lns
string lso[], lst[], lstg, lsa[], lse[]
long lc, n, c, m
str_resize lstr[]
CONSTANT string IS_ANCHOR = "1"

//load services
anv_svc.of_loadsvc(lnd, CSvc.DW)
anv_svc.of_loadsvc(lnc, CSvc.ISEMPTY)
anv_svc.of_loadsvc(lns, CSvc.STRING)

TRY
   //get dwobjects
   lc = lnd.of_getobjects(anv_svc, adw, lso, lst)
CATCH (n_x_svc ex)
   //an exception occured, exit
   RETURN
END TRY

attrib = lstr

FOR n = 1 to lc
   //init array, ctr
   lsa = lse
   c = 0
   //check each object for resizing
   TRY
      lstg = lnd.of_gettagkeyword(anv_svc, adw, lso[n], ANCHOR)
   CATCH (n_x_svc ex2)
      //swallow errors
   END TRY
   DO WHILE NOT lnc.of_isempty(lstg)
      c ++
      lsa[c] = lns.of_gettoken(lstg, ",")
   LOOP
   
   //must be 4
   IF c < 4 THEN CONTINUE
   
   m ++
   //set attributes
   attrib[m].ControlName = lso[n]
   attrib[m].AnchorTop = (lsa[1] = IS_ANCHOR)
   attrib[m].AnchorLeft = (lsa[2] = IS_ANCHOR)
   attrib[m].AnchorRight = (lsa[3] = IS_ANCHOR)
   attrib[m].AnchorBottom = (lsa[4] = IS_ANCHOR)
NEXT
end subroutine

public subroutine of_resize (u_dw adw, ref str_resize attrib[], readonly integer oldwidth, readonly integer oldheight, readonly integer newwidth, readonly integer newheight);long n, lc
long x, y, w, h, llt
string lsm, lsn

lc = UPPERBOUND(attrib)

FOR n = 1 to lc
   //skip invisibles
   IF adw.Describe(attrib[n].ControlName + ".visible") <> "1" THEN CONTINUE
   
   //init variables for anchor mode
   x = LONG(adw.Describe(attrib[n].ControlName + ".X"))
   y = LONG(adw.Describe(attrib[n].ControlName + ".Y"))
   w = LONG(adw.Describe(attrib[n].ControlName + ".width"))
   h = LONG(adw.Describe(attrib[n].ControlName + ".height"))
   
   IF attrib[n].AnchorRight THEN
      llt = newwidth - oldwidth
      IF NOT attrib[n].AnchorLeft THEN
            x += llt
      ELSE
            w += llt
      END IF
   END IF
   
   //check for minimum width
// IF w < MINWIDTH THEN w = MINWIDTH
// IF w < 0 THEN w = 1
   
   IF attrib[n].AnchorBottom THEN
      llt = newheight - oldheight
      IF NOT attrib[n].AnchorTop THEN
            y += llt
      ELSE
            h += llt
      END IF
   END IF   
   lsn = attrib[n].ControlName
   lsm += lsn + ".X=" + STRING(x) + CString.SPACE + &
          lsn + ".Y=" + STRING(y) + CString.SPACE + &
          lsn + ".width=" + STRING(w) + CString.SPACE + &
          lsn + ".height=" + STRING(h) + CString.SPACE
NEXT

//one hit
adw.Modify(lsm)
end subroutine

on n_svc_resize.create
call super::create
end on

on n_svc_resize.destroy
call super::destroy
end on