File: n_svc_splitcontainer.sru
Size: 19527
Date: Mon, 07 Apr 2008 21:31:40 +0200
$PBExportHeader$n_svc_splitcontainer.sru
$PBExportComments$Split Container Service
forward
global type n_svc_splitcontainer from n_svc_base
end type
end forward

global type n_svc_splitcontainer from n_svc_base
end type
global n_svc_splitcontainer n_svc_splitcontainer

type prototypes
FUNCTION ulong SetParent(ulong hWndChild,ulong hWndNewParent) LIBRARY "user32.dll"
end prototypes
type variables
Private:

long DragColor = Ccolor.BUTTON_SHADOW
end variables

forward prototypes
public subroutine of_setsplitcontrols (u_splitcontainer auo_container, readonly string as_lefttop, readonly string as_rightbottom)
public subroutine of_unregistercontrols (u_splitcontainer auo_container, dragobject ado_lefttop, dragobject ado_rightbottom)
public subroutine of_resizecontrols (u_splitcontainer auo_container, readonly boolean ab_vertical, readonly integer ai_splitterlocation, readonly integer ai_splitterwidth, readonly integer ai_splitpart, readonly integer ai_minimumcontrolsize, readonly dragobject ado_lefttop, readonly dragobject ado_rightbottom)
protected subroutine of_showpart (u_splitcontainer auo_container, readonly dragobject ado_part)
public subroutine of_capturemouse (u_splitcontainer auo_splitcontainer, ref rect astr_capture)
public subroutine of_releasemouse (rect astr_capture)
public subroutine of_registercontrols (u_splitcontainer auo_container, windowobject ado_lefttop, windowobject ado_rightbottom)
public subroutine of_resizecontrols (u_splitcontainer auo_container, readonly boolean ab_vertical, readonly integer ai_splitterlocation, readonly integer ai_splitterwidth, readonly integer ai_splitpart, readonly integer ai_minimumcontrolsize, readonly dragobject ado_lefttop, readonly mdiclient ado_rightbottom)
protected subroutine of_showpart (u_splitcontainer auo_container, readonly mdiclient ado_part)
public subroutine of_resizecontrols (u_splitcontainer auo_container, readonly boolean ab_vertical, readonly integer ai_splitterlocation, readonly integer ai_splitterwidth, readonly integer ai_splitpart, readonly integer ai_minimumcontrolsize, readonly mdiclient ado_lefttop, readonly dragobject ado_rightbottom)
end prototypes

public subroutine of_setsplitcontrols (u_splitcontainer auo_container, readonly string as_lefttop, readonly string as_rightbottom);Window lw
UserObject luo
PowerObject lpo
WindowObject lwo[]

lpo = auo_container.GetParent()

IF lpo.typeof() = Window! THEN
   lw = lpo
   lwo = lw.Control
ELSEIF lpo.typeof() = UserObject! THEN
   luo = lpo
   lwo = luo.Control
ELSE
   RETURN
END IF

long i, ll_upper
dragobject ldo_lefttop, ldo_rightbottom
mdiclient lmdi, lmdi_l

ll_upper = UPPERBOUND(lwo)

FOR i = 1 TO ll_upper
   IF lower(ClassName(lwo[i])) = lower(as_lefttop) THEN
      IF lwo[i].TypeOf() = mdiclient! THEN
         lmdi_l = lwo[i]
      ELSE
         ldo_lefttop = lwo[i]
      END IF
   ELSEIF lower(ClassName(lwo[i])) = lower(as_rightbottom) THEN
      IF lwo[i].TypeOf() = mdiclient! THEN
         lmdi = lwo[i]
      ELSE
         ldo_rightBottom = lwo[i]
      END IF
   END IF
NEXT

//throw an exception for invalid controls
IF (NOT ISVALID(ldo_lefttop)) OR (NOT ISVALID(ldo_rightbottom)) THEN
// n_x lx
// lx = CREATE n_x
// lx.SetMessage("Invalid control specified for Splitter Container.")
// THROW lx
END IF

//set split container controls
this.of_registercontrols(auo_container, ldo_lefttop, ldo_rightbottom)

IF ISVALID(lmdi) THEN
   auo_container.of_setsplitcontrols(ldo_lefttop, lmdi)
ELSEIF ISVALID(lmdi_l) THEN
   auo_container.of_setsplitcontrols(lmdi_l, ldo_rightbottom)
ELSE
   auo_container.of_setsplitcontrols(ldo_lefttop, ldo_rightbottom)
END IF
end subroutine

public subroutine of_unregistercontrols (u_splitcontainer auo_container, dragobject ado_lefttop, dragobject ado_rightbottom);//move controls to container
SetParent(Handle(ado_lefttop), Handle(auo_container.GetParent()))
SetParent(Handle(ado_rightbottom), Handle(auo_container.GetParent()))
end subroutine

public subroutine of_resizecontrols (u_splitcontainer auo_container, readonly boolean ab_vertical, readonly integer ai_splitterlocation, readonly integer ai_splitterwidth, readonly integer ai_splitpart, readonly integer ai_minimumcontrolsize, readonly dragobject ado_lefttop, readonly dragobject ado_rightbottom);integer li_splitstart
integer li_lefttop_newx, li_lefttop_newy, li_lefttop_newwidth, li_lefttop_newheight
integer li_rightbottom_newx, li_rightbottom_newy, li_rightbottom_newwidth, li_rightbottom_newheight

//bypass split if only one part to show
IF ai_splitpart <> 0 THEN
   IF ai_splitpart = 1 THEN
      IF ado_rightbottom.Visible THEN ado_rightbottom.Visible = FALSE
      of_showpart(auo_container, ado_lefttop)
   ELSE
      IF ado_lefttop.Visible THEN ado_lefttop.Visible = FALSE
      of_showpart(auo_container, ado_rightbottom)
   END IF
   RETURN
END IF

auo_container.SetRedraw(FALSE)

//restore visibility
IF NOT ado_rightbottom.Visible THEN ado_rightbottom.Visible = TRUE
IF NOT ado_lefttop.Visible THEN ado_lefttop.Visible = TRUE

IF ab_vertical THEN
   IF ai_splitterlocation > 0 THEN
      li_splitstart = ai_splitterlocation - ai_splitterwidth
   ELSE
      li_splitstart = ado_lefttop.height
   END IF
   
   //size and position
   li_lefttop_newx = 0
   li_lefttop_newy = 0
   
   li_lefttop_newwidth = auo_container.Width
   li_lefttop_newheight = li_splitstart
   
   li_splitstart += ai_splitterwidth

   li_rightbottom_newx = 0
   li_rightbottom_newy = li_splitstart
   
   li_rightbottom_newwidth = auo_container.Width
   li_rightbottom_newheight = auo_container.Height - li_splitstart   
   
   IF ado_lefttop.X <> li_lefttop_newx OR ado_lefttop.Y <> li_lefttop_newy THEN
      ado_lefttop.Move(li_lefttop_newx, li_lefttop_newx)
   END IF
      
   //resize only when not minimumsize
   IF li_lefttop_newheight >= ai_minimumcontrolsize AND li_rightbottom_newheight >= ai_minimumcontrolsize THEN
      IF ado_lefttop.Width <> li_lefttop_newwidth OR ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Resize(li_lefttop_newwidth, li_lefttop_newheight)
      END IF
      
      IF ado_rightbottom.X <> li_rightbottom_newx OR ado_rightbottom.Y <> li_rightbottom_newy THEN
         ado_rightbottom.Move(li_rightbottom_newx, li_rightbottom_newy)
      END IF
      
      IF ado_rightbottom.Width <> li_rightbottom_newwidth OR ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Resize(li_rightbottom_newwidth, li_rightbottom_newheight)
      END IF
   ELSE
      IF ado_lefttop.Width <> li_lefttop_newwidth THEN
         ado_lefttop.Width = li_lefttop_newwidth
      END IF
      IF ado_rightbottom.Width <> li_rightbottom_newwidth THEN
         ado_rightbottom.Width = li_rightbottom_newwidth
      END IF
   END IF

ELSE
   IF ai_splitterlocation > 0 THEN
      li_splitstart = ai_splitterlocation - ai_splitterwidth
   ELSE
      li_splitstart = ado_lefttop.width
   END IF
   
   //size and position
   li_lefttop_newx = 0
   li_lefttop_newy = 0
   
   li_lefttop_newwidth = li_splitstart
   li_lefttop_newheight = auo_container.Height
   
   li_splitstart += ai_splitterwidth

   li_rightbottom_newx = li_splitstart
   li_rightbottom_newy = 0
   
   li_rightbottom_newwidth = auo_container.Width - li_splitstart
   li_rightbottom_newheight = auo_container.Height 
   
   IF ado_lefttop.X <> li_lefttop_newx OR ado_lefttop.Y <> li_lefttop_newy THEN
      ado_lefttop.Move(li_lefttop_newx, li_lefttop_newx)
   END IF
      
   //resize only when not minimumsize
   IF li_lefttop_newwidth >= ai_minimumcontrolsize AND li_rightbottom_newwidth >= ai_minimumcontrolsize THEN
      IF ado_lefttop.Width <> li_lefttop_newwidth OR ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Resize(li_lefttop_newwidth, li_lefttop_newheight)
      END IF

      IF ado_rightbottom.X <> li_rightbottom_newx OR ado_rightbottom.Y <> li_rightbottom_newy THEN
         ado_rightbottom.Move(li_rightbottom_newx, li_rightbottom_newy)
      END IF

      IF ado_rightbottom.Width <> li_rightbottom_newwidth OR ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Resize(li_rightbottom_newwidth, li_rightbottom_newheight)
      END IF
   ELSE
      IF ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Height = li_lefttop_newheight
      END IF
      IF ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Height = li_rightbottom_newheight
      END IF
   END IF
END IF

auo_container.of_setsplitterlocation(li_splitstart)

auo_container.SetRedraw(TRUE)
end subroutine

protected subroutine of_showpart (u_splitcontainer auo_container, readonly dragobject ado_part);auo_container.SetRedraw(FALSE)

IF ado_part.X <> 0 OR ado_part.Y <> 0 THEN
   ado_part.Move(0, 0)
END IF

IF ado_part.Width <> auo_container.Width OR ado_part.Height <> auo_container.Height THEN
   ado_part.Resize(auo_container.Width, auo_container.Height)  
END IF

IF NOT ado_part.Visible THEN ado_part.Visible = TRUE

auo_container.SetRedraw(TRUE)
end subroutine

public subroutine of_capturemouse (u_splitcontainer auo_splitcontainer, ref rect astr_capture);n_svc_mgr lnsvc
n_svc_win32 lnv_win32
RECT lstr

//load service
lnsvc.of_loadsvc(lnv_win32, Csvc.WIN32)
//capture mouse
lnv_win32.SetCapture(Handle(auo_splitcontainer))
lnv_win32.GetClipcursor(astr_capture)
lnv_win32.GetWindowRect(Handle(auo_splitcontainer), lstr)
//clip mouse
lnv_win32.ClipCursor(lstr)
//set dragcolor
auo_splitcontainer.BackColor = DragColor
end subroutine

public subroutine of_releasemouse (rect astr_capture);n_svc_mgr lnsvc
n_svc_win32 lnv_win32

//load service
lnsvc.of_loadsvc(lnv_win32, Csvc.WIN32)
//restore mouse clip and release capture
lnv_win32.ClipCursor(astr_capture)
lnv_win32.ReleaseCapture()
end subroutine

public subroutine of_registercontrols (u_splitcontainer auo_container, windowobject ado_lefttop, windowobject ado_rightbottom);//move controls to container
SetParent(Handle(ado_lefttop), Handle(auo_container))
SetParent(Handle(ado_rightbottom), Handle(auo_container))
end subroutine

public subroutine of_resizecontrols (u_splitcontainer auo_container, readonly boolean ab_vertical, readonly integer ai_splitterlocation, readonly integer ai_splitterwidth, readonly integer ai_splitpart, readonly integer ai_minimumcontrolsize, readonly dragobject ado_lefttop, readonly mdiclient ado_rightbottom);integer li_splitstart
integer li_lefttop_newx, li_lefttop_newy, li_lefttop_newwidth, li_lefttop_newheight
integer li_rightbottom_newx, li_rightbottom_newy, li_rightbottom_newwidth, li_rightbottom_newheight

//bypass split if only one part to show
IF ai_splitpart <> 0 THEN
   IF ai_splitpart = 1 THEN
      IF ado_rightbottom.Visible THEN ado_rightbottom.Visible = FALSE
      of_showpart(auo_container, ado_lefttop)
   ELSE
      IF ado_lefttop.Visible THEN ado_lefttop.Visible = FALSE
      of_showpart(auo_container, ado_rightbottom)
   END IF
   RETURN
END IF

auo_container.SetRedraw(FALSE)

//restore visibility
IF NOT ado_rightbottom.Visible THEN ado_rightbottom.Visible = TRUE
IF NOT ado_lefttop.Visible THEN ado_lefttop.Visible = TRUE

IF ab_vertical THEN
   IF ai_splitterlocation > 0 THEN
      li_splitstart = ai_splitterlocation - ai_splitterwidth
   ELSE
      li_splitstart = ado_lefttop.height
   END IF
   
   //size and position
   li_lefttop_newx = 0
   li_lefttop_newy = 0
   
   li_lefttop_newwidth = auo_container.Width
   li_lefttop_newheight = li_splitstart
   
   li_splitstart += ai_splitterwidth

   li_rightbottom_newx = 0
   li_rightbottom_newy = li_splitstart + auo_container.Y
   
   li_rightbottom_newwidth = auo_container.Width
   li_rightbottom_newheight = auo_container.Height - li_splitstart   
   
   IF ado_lefttop.X <> li_lefttop_newx OR ado_lefttop.Y <> li_lefttop_newy THEN
      ado_lefttop.Move(li_lefttop_newx, li_lefttop_newx)
   END IF
      
   //resize only when not minimumsize
   IF li_lefttop_newheight >= ai_minimumcontrolsize AND li_rightbottom_newheight >= ai_minimumcontrolsize THEN
      IF ado_lefttop.Width <> li_lefttop_newwidth OR ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Resize(li_lefttop_newwidth, li_lefttop_newheight)
      END IF
      
      IF ado_rightbottom.X <> li_rightbottom_newx OR ado_rightbottom.Y <> li_rightbottom_newy THEN
         ado_rightbottom.Move(li_rightbottom_newx, li_rightbottom_newy)
      END IF
      
      IF ado_rightbottom.Width <> li_rightbottom_newwidth OR ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Resize(li_rightbottom_newwidth, li_rightbottom_newheight)
      END IF
   ELSE
      IF ado_lefttop.Width <> li_lefttop_newwidth THEN
         ado_lefttop.Width = li_lefttop_newwidth
      END IF
      IF ado_rightbottom.Width <> li_rightbottom_newwidth THEN
         ado_rightbottom.Width = li_rightbottom_newwidth
      END IF
   END IF

ELSE
   IF ai_splitterlocation > 0 THEN
      li_splitstart = ai_splitterlocation - ai_splitterwidth
   ELSE
      li_splitstart = ado_lefttop.width
   END IF
   
   //size and position
   li_lefttop_newx = 0
   li_lefttop_newy = 0
   
   li_lefttop_newwidth = li_splitstart
   li_lefttop_newheight = auo_container.Height
   
   li_splitstart += ai_splitterwidth

   li_rightbottom_newx = li_splitstart
   li_rightbottom_newy = auo_container.Y
   
   li_rightbottom_newwidth = auo_container.Width - li_splitstart
   li_rightbottom_newheight = auo_container.Height 
   
   IF ado_lefttop.X <> li_lefttop_newx OR ado_lefttop.Y <> li_lefttop_newy THEN
      ado_lefttop.Move(li_lefttop_newx, li_lefttop_newx)
   END IF
      
   //resize only when not minimumsize
   IF li_lefttop_newwidth >= ai_minimumcontrolsize AND li_rightbottom_newwidth >= ai_minimumcontrolsize THEN
      IF ado_lefttop.Width <> li_lefttop_newwidth OR ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Resize(li_lefttop_newwidth, li_lefttop_newheight)
      END IF

//    IF ado_rightbottom.X <> li_rightbottom_newx OR ado_rightbottom.Y <> li_rightbottom_newy THEN
         ado_rightbottom.Move(li_rightbottom_newx, li_rightbottom_newy)
//    END IF

      IF ado_rightbottom.Width <> li_rightbottom_newwidth OR ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Resize(li_rightbottom_newwidth, li_rightbottom_newheight)
      END IF
   ELSE
      IF ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Height = li_lefttop_newheight
      END IF
      IF ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Height = li_rightbottom_newheight
      END IF
   END IF
END IF

auo_container.of_setsplitterlocation(li_splitstart)

auo_container.SetRedraw(TRUE)
end subroutine

protected subroutine of_showpart (u_splitcontainer auo_container, readonly mdiclient ado_part);auo_container.SetRedraw(FALSE)

IF ado_part.X <> 0 OR ado_part.Y <> auo_container.Y THEN
   ado_part.Move(0, auo_container.Y)
END IF

IF ado_part.Width <> auo_container.Width OR ado_part.Height <> auo_container.Height THEN
   ado_part.Resize(auo_container.Width, auo_container.Height)  
END IF

IF NOT ado_part.Visible THEN ado_part.Visible = TRUE

auo_container.SetRedraw(TRUE)
end subroutine

public subroutine of_resizecontrols (u_splitcontainer auo_container, readonly boolean ab_vertical, readonly integer ai_splitterlocation, readonly integer ai_splitterwidth, readonly integer ai_splitpart, readonly integer ai_minimumcontrolsize, readonly mdiclient ado_lefttop, readonly dragobject ado_rightbottom);integer li_splitstart
integer li_lefttop_newx, li_lefttop_newy, li_lefttop_newwidth, li_lefttop_newheight
integer li_rightbottom_newx, li_rightbottom_newy, li_rightbottom_newwidth, li_rightbottom_newheight

//bypass split if only one part to show
IF ai_splitpart <> 0 THEN
   IF ai_splitpart = 1 THEN
      IF ado_rightbottom.Visible THEN ado_rightbottom.Visible = FALSE
      of_showpart(auo_container, ado_lefttop)
   ELSE
      IF ado_lefttop.Visible THEN ado_lefttop.Visible = FALSE
      of_showpart(auo_container, ado_rightbottom)
   END IF
   RETURN
END IF

auo_container.SetRedraw(FALSE)

//restore visibility
IF NOT ado_rightbottom.Visible THEN ado_rightbottom.Visible = TRUE
IF NOT ado_lefttop.Visible THEN ado_lefttop.Visible = TRUE

IF ab_vertical THEN
   IF ai_splitterlocation > 0 THEN
      li_splitstart = ai_splitterlocation - ai_splitterwidth
   ELSE
      li_splitstart = ado_lefttop.height
   END IF
   
   //size and position
   li_lefttop_newx = 0
   li_lefttop_newy = auo_container.Y
   
   li_lefttop_newwidth = auo_container.Width
   li_lefttop_newheight = li_splitstart
   
   li_splitstart += ai_splitterwidth

   li_rightbottom_newx = 0
   li_rightbottom_newy = li_splitstart
   
   li_rightbottom_newwidth = auo_container.Width
   li_rightbottom_newheight = auo_container.Height - li_splitstart   
   
   IF ado_lefttop.X <> li_lefttop_newx OR ado_lefttop.Y <> li_lefttop_newy THEN
      ado_lefttop.Move(li_lefttop_newx, li_lefttop_newx)
   END IF
      
   //resize only when not minimumsize
   IF li_lefttop_newheight >= ai_minimumcontrolsize AND li_rightbottom_newheight >= ai_minimumcontrolsize THEN
      IF ado_lefttop.Width <> li_lefttop_newwidth OR ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Resize(li_lefttop_newwidth, li_lefttop_newheight)
      END IF
      
      IF ado_rightbottom.X <> li_rightbottom_newx OR ado_rightbottom.Y <> li_rightbottom_newy THEN
         ado_rightbottom.Move(li_rightbottom_newx, li_rightbottom_newy)
      END IF
      
      IF ado_rightbottom.Width <> li_rightbottom_newwidth OR ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Resize(li_rightbottom_newwidth, li_rightbottom_newheight)
      END IF
   ELSE
      IF ado_lefttop.Width <> li_lefttop_newwidth THEN
         ado_lefttop.Width = li_lefttop_newwidth
      END IF
      IF ado_rightbottom.Width <> li_rightbottom_newwidth THEN
         ado_rightbottom.Width = li_rightbottom_newwidth
      END IF
   END IF

ELSE
   IF ai_splitterlocation > 0 THEN
      li_splitstart = ai_splitterlocation - ai_splitterwidth
   ELSE
      li_splitstart = ado_lefttop.width
   END IF
   
   //size and position
   li_lefttop_newx = 0
   li_lefttop_newy = auo_container.Y
   
   li_lefttop_newwidth = li_splitstart
   li_lefttop_newheight = auo_container.Height
   
   li_splitstart += ai_splitterwidth

   li_rightbottom_newx = li_splitstart
   li_rightbottom_newy = 0
   
   li_rightbottom_newwidth = auo_container.Width - li_splitstart
   li_rightbottom_newheight = auo_container.Height 
   
   IF ado_lefttop.X <> li_lefttop_newx OR ado_lefttop.Y <> li_lefttop_newy THEN
      ado_lefttop.Move(li_lefttop_newx, li_lefttop_newx)
   END IF
      
   //resize only when not minimumsize
   IF li_lefttop_newwidth >= ai_minimumcontrolsize AND li_rightbottom_newwidth >= ai_minimumcontrolsize THEN
      IF ado_lefttop.Width <> li_lefttop_newwidth OR ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Resize(li_lefttop_newwidth, li_lefttop_newheight)
      END IF

      IF ado_rightbottom.X <> li_rightbottom_newx OR ado_rightbottom.Y <> li_rightbottom_newy THEN
         ado_rightbottom.Move(li_rightbottom_newx, li_rightbottom_newy)
      END IF

      IF ado_rightbottom.Width <> li_rightbottom_newwidth OR ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Resize(li_rightbottom_newwidth, li_rightbottom_newheight)
      END IF
   ELSE
      IF ado_lefttop.Height <> li_lefttop_newheight THEN
         ado_lefttop.Height = li_lefttop_newheight
      END IF
      IF ado_rightbottom.Height <> li_rightbottom_newheight THEN
         ado_rightbottom.Height = li_rightbottom_newheight
      END IF
   END IF
END IF

auo_container.of_setsplitterlocation(li_splitstart)

auo_container.SetRedraw(TRUE)
end subroutine

on n_svc_splitcontainer.create
call super::create
end on

on n_svc_splitcontainer.destroy
call super::destroy
end on