//////////////////////////////////////////////////////////////////////
//
// MAIN.PRG
//
// Copyright:
// Alaska Software, (c) 2015-2020. All rights reserved.
//
// Contents:
// This example program demonstrates using the XbpHTMLStyle class
// for developing custom controls. To do this, HTML and CSS are
// used to define the visualization of the control, which
// includes using transition effects during state changes. In
// addition, the behavior of the control is defined. For example,
// for when certain HTML elements are clicked using the mouse.
// For this, event handlers are bound to individual HTML elements
// using the interfaces of the XbpHTMLWindow class.
//
//////////////////////////////////////////////////////////////////////
#include "Common.ch"
#include "xbp.ch"
#include "gra.ch"
#include "appevent.ch"
#pragma library( "adac20b.lib" )
#define EVENTVIEWER_NAMEID 133
PROCEDURE Main
LOCAL oXbp := Nil
LOCAL oDlg
LOCAL oEvt
Local nEvent, mp1 := Nil, mp2 := Nil, oXbpx := Nil
/*
* Open the parts table
*/
SET DEFAULT TO .\data
OpenParts()
/*
* Create the main window with an instance
* of the custom control. Also create a
* small window for logging events generated
* by the user operating the control.
*/
oDlg := XbpDialog():new( AppDesktop() )
oDlg:title := "Sliding List Example"
oDlg:taskList := .T.
oDlg:drawingArea:colorBG := GRA_CLR_WHITE
oDlg:drawingArea:clipChildren := .T.
oDlg:visible := .F.
oDlg:create( ,,, {640,400} )
CenterControl( oDlg )
oEvt := CreateEventViewer( oDlg )
// HTMLWindow below replaces XbpSlidingList object
/***********************
oXbp := XbpSlidingList():new( oDlg:DrawingArea )
oXbp:workArea := "parts"
oXbp:itemId := {|| parts->partno}
oXbp:itemCaption := {|| parts->partname}
oXbp:itemImage := {|| parts->bmpimage}
oXbp:itemTexts := {{"Size:", {|| parts->parttype}},;
{"Purchase Price:", {|| parts->purchase}},;
{"Sell Price:", {|| parts->sellprice}}}
oXbp:itemExpanded := {|oItem| LogEvent("Item [id:" + oItem:Id + "] was expanded.")}
oXbp:itemCollapsed:= {|oItem| LogEvent("Item [id:" + oItem:Id + "] was collapsed.")}
oXbp:layoutAlign := XBPLAYOUT_LEFT + XBPLAYOUT_TOP + ;
XBPLAYOUT_RIGHT + XBPLAYOUT_BOTTOM
oXbp:create( ,, {0,5}, {520,350} )
**************************/
oXbp := XbpPushButton():New( oDlg:DrawingArea )
oXbp:caption := "Ok"
oXbp:default := .T.
oXbp:layoutAlign := XBPLAYOUT_RIGHT + XBPLAYOUT_BOTTOM
oXbp:activate := {|| oEvt:destroy(), oEvt := Nil, PostAppEvent( xbeP_Close,,, oDlg ) }
oXbp:create( ,, {oDlg:DrawingArea:currentSize()[1]-90,15}, {80,30} )
HTMLWindow(@oDlg)
oEvt:show()
// oDlg:show() // sys-buttons are ignored if we do not use showmodal()
oDlg:showmodal()
nEvent := xbeP_None
DO WHILE nEvent <> xbeP_Close
nEvent := AppEvent( @mp1, @mp2, @oXbpx )
oXbp:handleEvent(nEvent,mp1,mp2)
ENDDO
if oEvt <> Nil
oEvt:Destroy()
endif
oDlg:Destroy()
RETURN
**************************************
Static Procedure HTMLWindow(oParent)
Local i, oXbp, cHTML, cItems := ''
Local aItems, oElement, bCode1, bCode2
// get each Li element
aItems := GetItems()
// Set element ID and add to items
For i := 1 to len(aItems)
aItems[i,1] := StrTran( aItems[i,1], "%ID%", Var2Char(i) )
cItems += aItems[i,1]
Next i
// loan the main html with SSC and insert all items
cHTML := LoadResource( "ITEMLIST",, "HTML", "neutral" )
cHTML := StrTran( cHTML, "%ITEMLIST%", cItems )
oXbp := XbpHTMLWindow():new(oParent, oParent)
oXbp:HTML := cHTML
oXbp:create( , , {0,5}, {oParent:DrawingArea:CurrentSize()[1]-100, oParent:DrawingArea:CurrentSize()[2]-10} )
For i := 1 to len(aItems)
bCode1 := aItems[i,2]
bCode2 := aItems[i,3]
oElement := oXbp:getNoIVar( "item" + Var2Char(i) )
oElement:expanded := &bCode1
oElement:collapsed := &bCode2
Next i
Return
***********
// Return array of HTML elements and codeblocks
// {HTML, Expended-codeblock, Collapsad-codeblock}
***********************************
Static Function GetItems()
Local nArea, cDetails, cTexts, cItem, i := 1
Local cBlockExp, cBlockCol, aReturn := {}
OpenParts()
nArea := Select()
(nArea)->(DbGoTop())
Do while !(nArea)->(EOF())
cTexts:= "" // three details cells
cDetails := LoadResource( "ITEMTEXTTEMPLATE",, "HTML", "neutral" ) // line 1
cDetails := StrTran( cDetails, "%TEXT1%", "Size:" )
cDetails := StrTran( cDetails, "%TEXT2%", (nArea)->parttype )
cTexts += cDetails
cDetails := LoadResource( "ITEMTEXTTEMPLATE",, "HTML", "neutral" ) // line 2
cDetails := StrTran( cDetails, "%TEXT1%", "Purchase Price:" )
cDetails := StrTran( cDetails, "%TEXT2%", AllTrim(Transform((nArea)->purchase, '99,999.99')) )
cTexts += cDetails
cDetails := LoadResource( "ITEMTEXTTEMPLATE",, "HTML", "neutral" ) // line 3
cDetails := StrTran( cDetails, "%TEXT1%", "Sell Price:" )
cDetails := StrTran( cDetails, "%TEXT2%", AllTrim(Transform((nArea)->sellprice, '99,999.99')) )
cTexts += cDetails
// load line item
cItem := LoadResource( "ITEMTEMPLATE",, "HTML", "neutral" )
IF i == 1
cItem := StrTran( cItem, "%DEFAULT%", "default" )
ELSE
cItem := StrTran( cItem, "%DEFAULT%", "" )
ENDIF
*
*** cItem := StrTran( cItem, "%ID%", Var2Char(i) )
cItem := StrTran( cItem, "%ITEMID%", (nArea)->partno )
cItem := StrTran( cItem, "%CAPTION%", (nArea)->partname )
cItem := StrTran( cItem, "%IMAGE%", ImageToThumbnailBase64((nArea)->bmpimage,30) )
cItem := StrTran( cItem, "%ITEMTEXTS%", cTexts )
cBlockExp := '{|u1,u2,oItem| LogEvent("Item [id:' + Var2Char(i) + '] was expanded.")}'
cBlockCol := '{|u1,u2,oItem| LogEvent("Item [id:' + Var2Char(i) + '] was collapsed.")}'
aadd( aReturn, {cItem, cBlockExp, cBlockCol} ) // each item := HTML and two codeblock
(nArea)->(DbSkip())
i++
ENDDO
(nArea)->(DbCloseArea())
Return aReturn
****************
/// Open the parts table
PROCEDURE OpenParts()
USE parts SHARED NEW
RETURN
/// Create a small auxiliary window for
/// displaying events generated by the user
/// Object to assign as the
/// owner of the event viewer
/// Window with the event list
///
/// The auxiliary window is positioned relative
/// to and moves with the owner
///
FUNCTION CreateEventViewer( oOwner )
LOCAL oDlg
LOCAL aPos
LOCAL aSize
LOCAL oXbp
aPos := oOwner:currentPos()
aPos[1] += oOwner:currentSize()[1]
aSize:= oOwner:currentSize()
aSize[1]:= 250
oDlg := XbpDialog():new( AppDesktop(), oOwner )
oDlg:title := "Event Viewer"
oDlg:taskList := .F.
oDlg:drawingArea:colorBG := GRA_CLR_WHITE
oDlg:visible := .F.
oDlg:create( ,, aPos, aSize )
oXbp := XbpListBox():new( oDlg:drawingArea )
oXbp:layoutAlign := XBPLAYOUT_LEFT + XBPLAYOUT_BOTTOM + ;
XBPLAYOUT_RIGHT + XBPLAYOUT_TOP
oXbp:create( ,,, {aSize[1]-30,aSize[2]-50} )
oXbp:setName( EVENTVIEWER_NAMEID )
CenterControl( oXbp )
RETURN oDlg
/// Add an event to the event viewer
/// String with the event
/// to be added
PROCEDURE LogEvent( cEvent )
LOCAL oXbp
// at this point there is no DBE (DbeSetDefault() returns NIL).
// Other settings (e.g. Deleted, Optimize, Rushmore, etc) are also lost
oXbp := AppDesktop():childFromName( EVENTVIEWER_NAMEID )
oXbp:addItem( cEvent )
RETURN
/// Set general display properties of the
/// application
PROCEDURE AppSys()
/*
* The application uses the ANSI character set
* and does not use a console window
*/
SET CHARSET TO ANSI
RETURN
/// Set general properties for database
/// access
PROCEDURE DbeSys()
/*
* Build the FOXCDX compound DBE and make
* it the default DBE of the application
*/
DbeLoad( "FOXDBE" )
DbeLoad( "CDXDBE" )
DbeBuild( "FOXCDX", "FOXDBE", "CDXDBE" )
DbeSetDefault( "FOXCDX" )
RETURN
// EOF