At first it works correctly then it makes an error and I haven't found the error
if the user activates a checkbox the procedure automatically activates a panel, the one that is free and displays it and inserts the controls for searching on xbrowse
if the user deactivates a checkbox the procedure deactivates the corresponding panel (at the time of activation an array is created where the number of the panel activated for that checkbox is stored)
When the procedure deactivates a panel it scrolls through the other remaining panels without leaving a void
the error occurs when the end user reactivates a previously deactivated checkbox
Code: Select all | Expand
#include "fivewin.ch"
#include "constant.ch"
#define DLG_nColorDlg RGB(245,245,235)
#define DLG_nColortitle1 RGB(219,230,244)
#define DLG_nColortitle2 RGB(207,221,239)
#define DLG_nColorBar1 RGB(250,250,245)
#define DLG_nColorBar2 RGB(245,245,235)
#define DLG_nColorBtn1 RGB(245,245,235)
#define DLG_nColorBtn2 RGB(250,250,245)
#define DLG_nColorBtnB RGB(195,195,185)
REQUEST DBFCDX
static l2Box,l3Box,l4Box
static nBoxNumber
STATIC aCheckboxPanelMap
function Main()
local oDlg, oBrw, oFont, oBold
local nBottom := 32.4
local nRight := 95
local nHt := nBottom * DLG_CHARPIX_H
local nWd := Max(nRight * DLG_CHARPIX_W, 180)
local oBox := Array(4)
local oDbf, oState
local nRow
local aState := {}
l2Box := .F.
l3Box := .F.
l4Box := .F.
aCheckboxPanelMap:=array(3)
oFont := TFont():New("TAHOMA", 0, 14)
oBold := TFont():New( "TAHOMA", 0, 14,,.t. )
oState := TDataBase():Open(nil, "STATES", "DBFCDX", .T.)
oState:gotop()
Do While !oState:eof()
AADD(aState, {oState:CODE, oState:NAME})
oState:skip()
enddo
oState:close()
oDbf := TDataBase():Open(nil, "CUSTOMER", "DBFCDX", .T.)
DEFINE DIALOG oDlg SIZE nWd, nHt PIXEL TRUEPIXEL;
FONT oFont COLOR CLR_BLACK, RGB(245,245,235);
STYLE nOR(DS_MODALFRAME, WS_POPUP, WS_CAPTION, WS_SYSMENU, WS_MINIMIZEBOX)
@ 40, 10 XBROWSE oBrw SIZE -10,-60 PIXEL OF oDlg;
DATASOURCE oDbf;
COLUMNS "ID", "CITY", "STATE", "MARRIED", "AGE";
CELL LINES NOBORDER UPDATE
WITH OBJECT oBrw
:nRowHeight := 25
:l2007 := .F.
:l2015 := .T.
:lRecordSelector := .F.
:nColDividerStyle := LINESTYLE_LIGHTGRAY
:nRowDividerStyle := LINESTYLE_LIGHTGRAY
:nStretchCol := STRETCHCOL_WIDEST
:nMarqueeStyle := MARQSTYLE_HIGHLROW
:SetChecks()
:lHScroll := .F.
:CreateFromCode()
END
nRow := 440
oBox[1] := PanelBox(nRow, 10, 30, oDlg:nWidth - 20, DLG_nColorBar1, DLG_nColorBar2,oDlg)
nRow -= 31
oBox[2] := PanelBox(nRow, 10, 30, oDlg:nWidth - 20, DLG_nColorBar1, DLG_nColorBar2,oDlg)
nRow -= 31
oBox[3] := PanelBox(nRow, 10, 30, oDlg:nWidth - 20, DLG_nColorBar1, DLG_nColorBar2,oDlg)
nRow -= 31
oBox[4] := PanelBox(nRow, 10, 30, oDlg:nWidth - 20,DLG_nColorBar1, DLG_nColorBar2,oDlg)
ACTIVATE DIALOG oDlg CENTERED;
ON INIT (oBox[2]:hide(), oBox[3]:hide(), oBox[4]:hide(),;
Form_Check(oBox, oDbf, oBrw, oDlg, aState))
return nil
Function Form_Check(oBox, oDbf, oBrw, oDlg, aState)
local cFilter := ""
local aFilters := { { .F., "AGE>20" }, { .F., "STATE='NY'" }, { .F., "MARRIED" } }
local aCheck[3], n
local nRow := 8
local nCol := 120
local oSay
@ 8, 40 SAY { || "FILTER : " + cFilter } SIZE 400, 25 PIXEL OF oDlg CENTER UPDATE TRANSPARENT
@ nRow, 5 SAY oSay PROMPT "Filter by" SIZE 80, 20 PIXEL OF oBox[1];
COLOR CLR_BLACK, Rgb(250,250,245)
oSay:lTransparent := .T.
for n := 1 to Len(aFilters)
aCheck[n] := CreateChk(nRow, nCol, oBox, aFilters, n, oDbf, @cFilter, oBrw, oDlg, aState)
aCheck[n]:lTransparent := .T.
aCheck[n]:setcolor(CLR_BLACK, rgb(210,210,205))
nCol += 160
if n == 3
EXIT
endif
next
return nil
static function CreateChk(nRow, nCol, oBox, aFilters, nIndex, oDbf, cFilter, oBrw, oDlg, aState)
local oChk
@ nRow, nCol CHECKBOX oChk VAR aFilters[nIndex, 1];
PROMPT aFilters[nIndex, 2] SIZE 150, 15 PIXEL OF oBox[1];
ON CHANGE (cFilter := ResetFilter(aFilters, oDbf, oBox, oBrw, aState, nIndex ), oDlg:Update())
return oChk
Function Refresh_Filter(oDbf, oBrw, cFilter, aFilters)
local af := {}
AEVAL(aFilters, { |a| If(a[1], AAdd(af, a[2]), nil) })
cFilter := FW_ArrayAsList(af, " .AND. ")
oDbf:SetFilter(cFilter)
oDbf:GoTop()
oBrw:Refresh()
return nil
function PanelBox(nTop, nLeft, nBottom, nRight, nClrLite, nClrDark,oDlg)
local oPanel,oBrush
Local aGrad := { nClrLite,nClrDark}
DEFINE BRUSH oBrush GRADIENT aGrad
oPanel:=Tpanel():New( nTop, nLeft,nTop+nBottom, nRight, oDlg)
oPanel:SetBrush( oBrush )
* oPanel:bPainted := { || oPanel:Box( 1,1,oPanel:nHeight-1,oPanel:nWidth-1 ) }
return oPanel
FUNCTION ActivateNextBox( oBox, l2Box, l3Box, l4Box, oDlgx )
local nPanel
IF l2Box
IF l3Box
IF l4Box
ELSE
oBox[4]:Show()
oDlgx := oBox[4]
l4Box := .T.
nPanel:= 4
ENDIF
ELSE
oBox[3]:Show()
oDlgx := oBox[3]
l3Box := .T.
nPanel:= 3
ENDIF
ELSE
oBox[2]:Show()
oDlgx := oBox[2]
l2Box := .T.
nPanel:= 2
ENDIF
RETURN nPanel
FUNCTION DeactivateBox( oBox, nIndex, l2Box, l3Box, l4Box, oDlgx )
DO CASE
CASE nIndex == 2
IF l2Box
oBox[2]:Hide()
l2Box := .F.
oDlgx := NIL
AdjustPanelPosition(oBox, 2)
ENDIF
CASE nIndex == 3
IF l3Box
oBox[3]:Hide()
l3Box := .F.
oDlgx := NIL
AdjustPanelPosition(oBox, 3)
ENDIF
CASE nIndex == 4
IF l4Box
oBox[4]:Hide()
l4Box := .F.
oDlgx := NIL
AdjustPanelPosition(oBox, 4)
ENDIF
ENDCASE
RETURN NIL
FUNCTION ActivatePanel(nCheckboxIndex, nPanelIndex)
aCheckboxPanelMap[nCheckboxIndex] := nPanelIndex
RETURN NIL
FUNCTION DeactivatePanel(nCheckboxIndex, oBox,oBrw)
LOCAL nPanelIndex := aCheckboxPanelMap[nCheckboxIndex]
IF nPanelIndex != NIL
oBox[nPanelIndex]:Hide()
aCheckboxPanelMap[nCheckboxIndex] := NIL
AdjustPanelPosition(oBox,oBrw)
ENDIF
RETURN NIL
FUNCTION AdjustPanelPosition(oBox, oBrw)
LOCAL nDesiredTop := 440
LOCAL nPanelHeight := 30
LOCAL nCurrentTop := nDesiredTop
LOCAL nActivePanels := 0
FOR nIndex := 2 TO LEN(oBox)
IF !Empty(oBox[nIndex])
nActivePanels++
ENDIF
NEXT
IF nActivePanels > 0
nCurrentTop -= nPanelHeight * nActivePanels
ENDIF
FOR nIndex := 2 TO LEN(oBox)
IF !Empty(oBox[nIndex])
oBox[nIndex]:nTop := nCurrentTop
nCurrentTop += nPanelHeight
ENDIF
NEXT
RETURN NIL
STATIC FUNCTION ResetFilter(aFilters, oDbf, oBox, oBrw, aState, nIndex)
LOCAL cFilter := ""
LOCAL af := {}
LOCAL cState := SPACE(25)
LOCAL lMarried := .F.
LOCAL nAge := 0
LOCAL oCmb, nState := 1
LOCAL nRow := 8
LOCAL oSay, oRadio, nRadio := 1, cMarried := ""
LOCAL oDlgx, i
LOCAL aAge := {"20", "40", "60"}
LOCAL nBoxHeight := 30
LOCAL nVisibleBoxHeight := 0
LOCAL oCtrl
LOCAL nPanel
oDlgx := NIL
IF aFilters[nIndex, 1]
nPanel := ActivateNextBox(oBox, @l2Box, @l3Box, @l4Box, @oDlgx)
nVisibleBoxHeight := 30
IF !Empty(oDlgx:acontrols)
FOR EACH oCtrl IN oDlgx:acontrols
oCtrl:hide()
NEXT
ENDIF
ActivatePanel(nIndex, nPanel)
DO CASE
CASE nIndex == 1
@ nRow, 5 SAY oSay PROMPT "Age:" SIZE 80, 20 PIXEL OF oDlgx;
COLOR CLR_BLACK, Rgb(250,250,245)
oSay:lTransparent := .T.
@ 0.4, 10 COMBOBOX oCmb VAR nAge ITEMS aAge;
SIZE 600, 90 OF oDlgx;
ON CHANGE (cFilter := 'AGE<' + LTrim(Str(nAge)),;
aFilters[1, 2] := cFilter,;
Refresh_Filter(oDbf, oBrw, @cFilter, aFilters))
CASE nIndex == 2
@ nRow, 5 SAY oSay PROMPT "State:" SIZE 80, 20 PIXEL OF oDlgx;
COLOR CLR_BLACK, Rgb(250,250,245)
oSay:lTransparent := .T.
@ 0.4, 10 COMBOBOX oCmb VAR nState ITEMS ArrTranspose(aState)[2];
SIZE 600, 90 OF oDlgx;
ON CHANGE (cState := aState[nState][1],;
cFilter := 'STATE=' + "'" + cState + "'",;
aFilters[2, 2] := cFilter,;
Refresh_Filter(oDbf, oBrw, @cFilter, aFilters))
CASE nIndex == 3
@ nRow, 5 SAY oSay PROMPT "Married:" SIZE 80, 20 PIXEL OF oDlgx;
COLOR CLR_BLACK, Rgb(250,250,245)
oSay:lTransparent := .T.
@ 1, 80 RADIO oRadio VAR nRadio OF oDlgx UPDATE SIZE 80, 25 PIXEL;
PROMPT "Married";
ON CHANGE (IF(nRadio == 1, cMarried := ".T.", cMarried := ".F."),;
cFilter := 'MARRIED=' + cMarried,;
aFilters[3, 2] := cFilter,;
Refresh_Filter(oDbf, oBrw, @cFilter, aFilters))
@ 1, 400 RADIOITEM "Not Married" RADIOMENU oRadio;
OF oDlgx PIXEL SIZE 80, 20
ENDCASE
ELSE
DeactivatePanel(nIndex, oBox,oBrw)
nVisibleBoxHeight -= 30
ENDIF
oBrw:nBottomMargin += nVisibleBoxHeight
AEVAL(aFilters, { |a| If(a[1], AAdd(af, a[2]), NIL) })
cFilter := FW_ArrayAsList(af, " .AND. ")
oDbf:SetFilter(cFilter)
oDbf:GoTop()
oBrw:Refresh()
RETURN cFilter