File: u_statusbar.sru
Size: 10032
Date: Mon, 07 Apr 2008 21:32:43 +0200
$PBExportHeader$u_statusbar.sru
$PBExportComments$PB friendly Common Control StatusBar
forward
global type u_statusbar from u_base_container
end type
type uo_1 from u_comctl_statusbar within u_statusbar
end type
type st_1 from statictext within u_statusbar
end type
type struc_layout from structure within u_statusbar
end type
end forward

type struc_layout from structure
   integer     id
   long     parts[]
end type

global type u_statusbar from u_base_container
integer width = 850
integer height = 80
boolean border = true
boolean #resizeobjects = false
event resize pbm_size
event parentnotify pbm_parentnotify
event ke_panedoubleclicked ( readonly integer ai_panel,  readonly string as_text )
uo_1 uo_1
st_1 st_1
end type
global u_statusbar u_statusbar

type prototypes
function long SendMessageLong( long hWindow, uint Msg, ulong wParam, Ref long Parts[] ) Library 'user32' alias for 'SendMessageA'
function long SendMessageString( long hWindow, uint Msg, ulong wParam, Ref string szText ) Library 'user32' alias for 'SendMessageA'
function long SendMessageRect( long hWindow, uint Msg, ulong wParam, Ref RECT lpRect ) Library 'user32' alias for 'SendMessageA'
end prototypes

type variables
Public:
Boolean #SizeGrip = TRUE, #AnchorLastPanel = TRUE
Private:
long il_origstyle, il_currentlayout
str_statusbar_layout istr_layouts[]
u_hpb iuo_progress
n_comctl_progressbar inv_progress
boolean ib_suspendresize
end variables

forward prototypes
public function integer of_addlayout (readonly str_statusbar_layout astr)
public subroutine of_setlayout (readonly integer ai_index)
public subroutine of_settext (readonly integer ai_part, readonly string as_text)
public subroutine of_showsizegrip (readonly boolean ab_show)
public subroutine of_seticon (readonly integer ai_part, readonly long ai_icon)
public subroutine of_anchorlastpanel (boolean ab)
public subroutine of_refreshlayout ()
public subroutine of_showprogress (readonly integer ai_panel)
public subroutine of_closeprogress ()
public subroutine of_stepprogress ()
protected subroutine of_recalclayout ()
end prototypes

event resize;IF NOT ib_suspendresize THEN uo_1.Resize(-1, -1)

IF parent.TypeOf() = Window! THEN
   Window lw
   
   lw = parent
   IF lw.WindowState = Maximized! THEN
      this.of_showsizegrip(FALSE)
   ELSE
      this.of_showsizegrip(TRUE)
   END IF
   //recalc parts
   IF #anchorlastpanel THEN
      
      IF UPPERBOUND(istr_layouts) < il_currentlayout OR il_currentlayout = 0 THEN RETURN
      //skip if no last panel width was set
      IF istr_layouts[il_currentlayout].lastpanelwidth <= 0 THEN RETURN
      
      long ll_parts[], ll_upper, n, ll_tot, ll_width, ll_add
      
      ll_width = UnitsToPixels(uo_1.width, XUnitsToPixels!)
      ll_parts = istr_layouts[il_currentlayout].parts
      ll_upper = UPPERBOUND(ll_parts)
      
      FOR n = 1 to ll_upper
         IF n = ll_upper THEN
            ll_add = ll_width - ll_tot - istr_layouts[il_currentlayout].lastpanelwidth
         ELSE
            ll_tot = ll_parts[n]
         END IF
      NEXT
      //add
      FOR n = 1 to ll_upper
         IF n = ll_upper THEN EXIT
         ll_parts[n] += ll_add
      NEXT
      istr_layouts[il_currentlayout].parts = ll_parts
      this.of_setlayout(il_currentlayout)
   END IF
END IF
end event

event ke_panedoubleclicked(readonly integer ai_panel, readonly string as_text);//fired when panel is doubleclicked
end event

public function integer of_addlayout (readonly str_statusbar_layout astr);long ll_upper, ll_id, n
boolean lb_found

ll_upper = UPPERBOUND(istr_layouts)
//check if similar layout exists
FOR n = 1 to ll_upper
   IF istr_layouts[n].parts = astr.parts THEN
      lb_found = TRUE
      EXIT
   END IF
NEXT

IF NOT lb_found THEN
   ll_id = ll_upper + 1
   istr_layouts[ll_id] = astr
   istr_layouts[ll_id].id = ll_id
ELSE
   ll_id = n
END IF

RETURN ll_id
end function

public subroutine of_setlayout (readonly integer ai_index);long ll_count, n

IF UPPERBOUND(istr_layouts) < ai_index THEN RETURN

//backup previous
IF il_currentlayout > 0 AND il_currentlayout <> ai_index THEN
   ll_count = UPPERBOUND(istr_layouts[il_currentlayout].parts)
   FOR n = 1 to ll_count
      uo_1.of_gettext( n - 1, istr_layouts[il_currentlayout].text[n])
      istr_layouts[il_currentlayout].icon[n] = uo_1.of_geticon( n - 1)
   NEXT
   uo_1.POST SetRedraw(TRUE)
END IF

uo_1.of_setparts(istr_layouts[ai_index].parts)

il_currentlayout = ai_index
//set text
ll_count = UPPERBOUND(istr_layouts[il_currentlayout].text)
FOR n = 1 to ll_count
   uo_1.of_settext( n - 1, 0, istr_layouts[il_currentlayout].text[n])
   //remove any icons
   uo_1.of_seticon(n - 1, -2)
   IF UPPERBOUND(istr_layouts[il_currentlayout].icon) >= n THEN uo_1.of_seticon( n - 1, istr_layouts[il_currentlayout].icon[n])
NEXT

of_Recalclayout()
end subroutine

public subroutine of_settext (readonly integer ai_part, readonly string as_text);IF il_currentlayout > 0 THEN istr_layouts[il_currentlayout].text[ai_part] = as_text
uo_1.of_settext(ai_part - 1, 0, as_text)
uo_1.SetRedraw(TRUE)
end subroutine

public subroutine of_showsizegrip (readonly boolean ab_show);n_svc_bit lnv_bit
n_svc_mgr lnv_svcman
//n_svc_exception lnv_x
n_svc_win32 lnv_win32
Boolean lb_isset
long ll_style

lnv_svcman.of_loadsvc(lnv_bit, CSvc.BIT)
lnv_svcman.of_loadsvc(lnv_win32, CSvc.WIN32)

ll_style = lnv_win32.GetWindowlong(Handle(uo_1), Cwin32.GWL_STYLE)

lb_isset = lnv_bit.of_bitwiseand({ll_style, Cwin32.SBARS_SIZEGRIP}) = Cwin32.SBARS_SIZEGRIP

IF ab_show THEN
   IF NOT lb_isset THEN
      ll_style = lnv_bit.of_bitwiseor({ll_style, Cwin32.SBARS_SIZEGRIP})
   END IF
ELSE
   IF lb_isset THEN
      ll_style -= Cwin32.//il_origstyle //lnv_bit.of_bitwiseor({uo_1.style, Cwin32.SBARS_SIZEGRIP})
   END IF
END IF

uo_1.style = ll_style
//lnv_win32.Setwindowlong(Handle(uo_1), Cwin32.GWL_STYLE, ll_style)

IF il_currentlayout > 0 THEN this.of_setlayout(il_currentlayout)//uo_1.of_setparts(istr_layouts[il_currentlayout].parts)
   
end subroutine

public subroutine of_seticon (readonly integer ai_part, readonly long ai_icon);istr_layouts[il_currentlayout].icon[ai_part] = ai_icon
uo_1.of_seticon(ai_part - 1, ai_icon)
uo_1.SetRedraw(TRUE)
end subroutine

public subroutine of_anchorlastpanel (boolean ab);#anchorlastpanel = ab
this.TriggerEvent("resize")
end subroutine

public subroutine of_refreshlayout ();this.TriggerEvent("resize")
end subroutine

public subroutine of_showprogress (readonly integer ai_panel);long ll_x, ll_y, ll_w, ll_h

uo_1.of_getrect(ai_panel - 1, ll_y, ll_x, ll_w, ll_h)

ll_w = ll_w - ll_x
ll_h = ll_h - ll_y

IF ISVALID(inv_progress) THEN DESTROY inv_progress
inv_progress = CREATE n_comctl_progressbar
inv_progress.of_createprogressbar(Handle(uo_1), 0, ll_x, ll_y, ll_w, ll_h)
inv_progress.of_setrange(0, 100)
inv_progress.of_setstep(1)
end subroutine

public subroutine of_closeprogress ();IF ISVALID(inv_progress) THEN
   inv_progress.of_destroy()
   DESTROY inv_progress
END IF
end subroutine

public subroutine of_stepprogress ();IF ISVALID(inv_progress) THEN
   inv_progress.of_Stepit()
END IF
end subroutine

protected subroutine of_recalclayout ();//recalc parts
IF #anchorlastpanel THEN
   
// ib_suspendresize = TRUE
   
   IF UPPERBOUND(istr_layouts) < il_currentlayout OR il_currentlayout = 0 THEN RETURN
   //skip if no last panel width was set
   IF istr_layouts[il_currentlayout].lastpanelwidth <= 0 THEN RETURN
   
   long ll_parts[], ll_upper, n, ll_tot, ll_width, ll_add
   
   ll_width = UnitsToPixels(uo_1.width, XUnitsToPixels!)
   ll_parts = istr_layouts[il_currentlayout].parts
   ll_upper = UPPERBOUND(ll_parts)
   
   FOR n = 1 to ll_upper
      IF n = ll_upper THEN
         ll_add = ll_width - ll_tot - istr_layouts[il_currentlayout].lastpanelwidth
      ELSE
         ll_tot = ll_parts[n]
      END IF
   NEXT
   //add
   FOR n = 1 to ll_upper
      IF n = ll_upper THEN EXIT
      ll_parts[n] += ll_add
   NEXT
   istr_layouts[il_currentlayout].parts = ll_parts
   uo_1.of_setparts(istr_layouts[il_currentlayout].parts)
END IF
end subroutine

on u_statusbar.create
int iCurrent
call super::create
this.uo_1=create uo_1
this.st_1=create st_1
iCurrent=UpperBound(this.Control)
this.Control[iCurrent+1]=this.uo_1
this.Control[iCurrent+2]=this.st_1
end on

on u_statusbar.destroy
call super::destroy
destroy(this.uo_1)
destroy(this.st_1)
end on

event constructor;long ll_w, ll_h, ll_s, ll_parts[]
long ll_top, ll_left, ll_right, ll_bottom

this.Border = FALSE
this.BringToTop = TRUE
st_1.BringToTop = FALSE
st_1.Visible = FALSE
uo_1.Visible = TRUE
//store default style
il_origstyle = this.style
uo_1.of_getborders(ll_w, ll_h, ll_s)
uo_1.of_getrect(0, ll_top, ll_left, ll_right, ll_bottom)
ll_h = ll_bottom
//adjust container
this.height = PixelsToUnits(ll_h, YPixelstoUnits!)
end event

type uo_1 from u_comctl_statusbar within u_statusbar
event doubleclicked pbm_lbuttondblclk
boolean visible = false
integer x = 110
integer width = 585
integer taborder = 10
end type

event doubleclicked;//MessageBox("", "DOWN")
long llpx, llpy, ll_parts[]
long ll_count, n
string ls_txt

llpx = UnitsToPixels(xpos, XUnitsToPixels!)

ll_count = uo_1.of_getparts(ll_parts)
FOR n = 1 to ll_count
   IF n < ll_count THEN
      IF llpx <= ll_parts[n] THEN
         uo_1.of_gettext(n - 1, ls_txt)
         parent.EVENT ke_panedoubleclicked(n, TRIM(ls_txt))
         EXIT
      END IF
   ELSE
      IF ll_parts[n] >= llpx OR ll_parts[n] = -1 THEN
         uo_1.of_gettext(n - 1, ls_txt)
         parent.EVENT ke_panedoubleclicked(n, TRIM(ls_txt))
         EXIT
      END IF
   END IF
NEXT
end event

type st_1 from statictext within u_statusbar
integer x = 155
integer y = 8
integer width = 512
integer height = 52
boolean bringtotop = true
integer textsize = -8
integer weight = 700
fontcharset fontcharset = ansi!
fontpitch fontpitch = variable!
fontfamily fontfamily = swiss!
string facename = "MS Sans Serif"
long textcolor = 33554432
long backcolor = 67108864
string text = "StatusBar Control"
boolean focusrectangle = false
end type