Antonio,
You are bringing a lot of things up to date in their appearance in .09 and .10, but I believe a significant enhancement would be to address the browse issue. tWBrowse may be fast but it lacks in appearance and flexibility.
I've been using tSBrowse for a much better capability, but I do notice it can be slow to load and it flickers. However, it adds some nice features that make it very helpful in a "real world" application.
1) The size of rows can be easily increased ( vertical ) to make the display more readable
2) Gradient colors can be used for the header ( and footer )
3) Cells can be editable
4) A column can be used for instant searching ( ie. you can set the order on a column, and start typing and reposition the highlight immediately ).
5) Column widths and alignment are easy to enact
6) It is easy to use alternate background colors on alternate rows.
The problem with tSBrowse is that it loads slowly, and it has not been updated in quite awhile, so it can lose compatibility with other improvements in FiveWin that we would assume are handled in the normal browses.
So ... perhaps others will contribute their thoughts on this being a positive enhancement area to follow your work with the outlook, button bar, and message bar improvements.
Suggested enhancement
Suggested enhancement
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
Hello Tim,
ad 4)
to get this functionality I use the following code.
Regards,
Otto
@ 3, 1 LISTBOX oLbx FIELDs STR(umsatz->renr) ...
@ 0.3,38 GET oSay VAR cFind OF oBar SIZE 160,26 UPDATE READONLY
oLbx:bkeyChar :={|nKey|iif(nKey == K_ENTER, ;
prn_RgKOPIE(nhorzM,nVertM), ;
cFind := KeySeek(nKey,oLbx_PR,oSay,@cFind) ) , ;
oLbx:SetFocus(),oLbx:Refresh() }
oLbx:bChange := {|| cFind := "" , oSay:Refresh() }
oLbx:aActions = Array( ( Alias())->(FCount() ) )
FOR n := 1 TO Len( oLbx:aActions)
IF n = 1
oLbx:aActions [n] ={|| cFind := "",oSay:Refresh() ,index_mrez(n:=1,oLbx)}
elseif n = 6
oLbx:aActions [n] ={|| cFind := "" , oSay:Refresh() ,index_mrez(n:=2,oLbx)}
elseif n = 2
oLbx:aActions [n] ={|| cFind := "" , oSay:Refresh() ,index_mrez(n:=3,oLbx)}
else
oLbx:aActions [n] ={|| cFind := "",oSay:Refresh(), tone(300,4)}
ENDIF
NEXT
+++++++++++++++++++++++++++++++++++++++++++++
func index_mrez(n,oLbX)
*--------------------------------------------
select lager
if n = 1
oLbx:aHeaders:={ "-> Bezeichnung", "|| Kategorie","Kartenpreis","Wareneinsatz","Nettorohaufschlag","|| Artikel-NR" }
set order to 5
elseif n = 2
oLbx:aHeaders:={ "|| Bezeichnung", "|| Kategorie","Kartenpreis","Wareneinsatz","Nettorohaufschlag","-> Artikel-NR" }
set order to 1
elseif n = 3
oLbx:aHeaders:={ "|| Bezeichnung", "-> Kategorie","Kartenpreis","Wareneinsatz","Nettorohaufschlag","|| Artikel-NR" }
set order to 3
endif
oLbx:refresh()
oLbx:SetFocus()
RETURN NIL
func KeySeek(nKey, oBrw, oSay, cSeek)
LOCAL cKey := upper( chr(nKey) )
LOCAL nRecno := recno()
LOCAL test := cSeek
* MSGINFO(str(nkey))
do case
CASE nKey == K_UP ; oBrw:up() ; cSeek := ""
CASE nKey == K_DOWN ; oBrw:down() ; cSeek := ""
* CASE nkey == K_LEFT ; oBrw:left() ; cSeek := ""
* CASE nkey == K_RIGHT ; oBrw:right() ; cSeek := ""
CASE nKey == K_PGUP ; oBrw:pageup() ; cSeek := ""
CASE nKey == K_PGDN ; oBrw:pagedown() ; cSeek := ""
CASE nKey == K_CTRL_PGUP ; oBrw:GoTop() ; cSeek := ""
CASE nKey == K_CTRL_PGDN ; oBrw:GoBottom() ; cSeek := ""
CASE nKey == K_HOME ; oBrw:GoTop() ; cSeek := ""
CASE nKey == K_END ; oBrw:GoBottom() ; cSeek := ""
OTHERWISE
IF nKey == K_BS
cSeek := Left(cSeek, Len(cSeek) - 1 )
else
cSeek := cSeek + cKey
ENDIF
if len(Alltrim(indexkey())) > 0
if "UPPER"$upper(ordkey())
cSeek=UPPER( (cSeek))
else
cSeek= (cSeek)
endif
dbseek(cSeek , .T. )
cSeek= (cSeek)
else
MsgInfo("Kein Index ausgewählt")
endif
IF Found()
oBrw:Refresh()
test := cSeek
oBrw:Upstable()
cSeek := test
else
cSeek := Left(cSeek, Len(cSeek) - 1 )
DbGoTo(nRecno)
ENDIF
endcase
oSay:Refresh() // ; oSay:SetText( cSeek )
RETURN( cSeek )
ad 4)
to get this functionality I use the following code.
Regards,
Otto
@ 3, 1 LISTBOX oLbx FIELDs STR(umsatz->renr) ...
@ 0.3,38 GET oSay VAR cFind OF oBar SIZE 160,26 UPDATE READONLY
oLbx:bkeyChar :={|nKey|iif(nKey == K_ENTER, ;
prn_RgKOPIE(nhorzM,nVertM), ;
cFind := KeySeek(nKey,oLbx_PR,oSay,@cFind) ) , ;
oLbx:SetFocus(),oLbx:Refresh() }
oLbx:bChange := {|| cFind := "" , oSay:Refresh() }
oLbx:aActions = Array( ( Alias())->(FCount() ) )
FOR n := 1 TO Len( oLbx:aActions)
IF n = 1
oLbx:aActions [n] ={|| cFind := "",oSay:Refresh() ,index_mrez(n:=1,oLbx)}
elseif n = 6
oLbx:aActions [n] ={|| cFind := "" , oSay:Refresh() ,index_mrez(n:=2,oLbx)}
elseif n = 2
oLbx:aActions [n] ={|| cFind := "" , oSay:Refresh() ,index_mrez(n:=3,oLbx)}
else
oLbx:aActions [n] ={|| cFind := "",oSay:Refresh(), tone(300,4)}
ENDIF
NEXT
+++++++++++++++++++++++++++++++++++++++++++++
func index_mrez(n,oLbX)
*--------------------------------------------
select lager
if n = 1
oLbx:aHeaders:={ "-> Bezeichnung", "|| Kategorie","Kartenpreis","Wareneinsatz","Nettorohaufschlag","|| Artikel-NR" }
set order to 5
elseif n = 2
oLbx:aHeaders:={ "|| Bezeichnung", "|| Kategorie","Kartenpreis","Wareneinsatz","Nettorohaufschlag","-> Artikel-NR" }
set order to 1
elseif n = 3
oLbx:aHeaders:={ "|| Bezeichnung", "-> Kategorie","Kartenpreis","Wareneinsatz","Nettorohaufschlag","|| Artikel-NR" }
set order to 3
endif
oLbx:refresh()
oLbx:SetFocus()
RETURN NIL
func KeySeek(nKey, oBrw, oSay, cSeek)
LOCAL cKey := upper( chr(nKey) )
LOCAL nRecno := recno()
LOCAL test := cSeek
* MSGINFO(str(nkey))
do case
CASE nKey == K_UP ; oBrw:up() ; cSeek := ""
CASE nKey == K_DOWN ; oBrw:down() ; cSeek := ""
* CASE nkey == K_LEFT ; oBrw:left() ; cSeek := ""
* CASE nkey == K_RIGHT ; oBrw:right() ; cSeek := ""
CASE nKey == K_PGUP ; oBrw:pageup() ; cSeek := ""
CASE nKey == K_PGDN ; oBrw:pagedown() ; cSeek := ""
CASE nKey == K_CTRL_PGUP ; oBrw:GoTop() ; cSeek := ""
CASE nKey == K_CTRL_PGDN ; oBrw:GoBottom() ; cSeek := ""
CASE nKey == K_HOME ; oBrw:GoTop() ; cSeek := ""
CASE nKey == K_END ; oBrw:GoBottom() ; cSeek := ""
OTHERWISE
IF nKey == K_BS
cSeek := Left(cSeek, Len(cSeek) - 1 )
else
cSeek := cSeek + cKey
ENDIF
if len(Alltrim(indexkey())) > 0
if "UPPER"$upper(ordkey())
cSeek=UPPER( (cSeek))
else
cSeek= (cSeek)
endif
dbseek(cSeek , .T. )
cSeek= (cSeek)
else
MsgInfo("Kein Index ausgewählt")
endif
IF Found()
oBrw:Refresh()
test := cSeek
oBrw:Upstable()
cSeek := test
else
cSeek := Left(cSeek, Len(cSeek) - 1 )
DbGoTo(nRecno)
ENDIF
endcase
oSay:Refresh() // ; oSay:SetText( cSeek )
RETURN( cSeek )
Browse
Thats a lot of code for a single listbox. The following code does all I mentioned when using tSBrowse:
REDEFINE BROWSE oLbu1 ID 2100 OF oDlu ON DBLCLICK ( cCode := oCod:code, oDlu:end( ) ) UPDATE
oLbu1:setoDBF( oCod )
add column to oLbu1 header "Code" data oCod:code ALIGN 0,1 size 150 ORDER "erfcod"
add column to oLbu1 Header "Description" data oCod:detail ALIGN 0,1 size 350
oDlu:oClient:= oLbu1
oLbu1:nLineStyle:=0
oLbu1:nHeightCell += 4
oLbu1:nHeightHead += 6
oLbu1:lNoHScroll := .T.
oLbu1:setColor( {1}, {CLR_BROWSETEXT} ) // cell text color
oLbu1:setColor( {4}, {{ CLR_HEADERTOP, CLR_HEADERBOT }} ) // degraded headers background color
oLbu1:setColor( {14}, {{ CLR_HEADERTOP, CLR_HEADERBOT }} ) // degraded headers background color
// Show alternating color in rows
lClrFlag:=.f.
oLbu1:bSkip:={| nRecs | (nRecs:= oCod:skipper( nRecs ), lClrFlag:=if(nRecs/2 = int(nRecs/2), lClrFlag,!lClrFlag), nRecs) }
oLbu1:setColor( { 2 }, { { || if(lClrFlag, CLR_PANE1, CLR_PANE2 ) }} )
REDEFINE BROWSE oLbu1 ID 2100 OF oDlu ON DBLCLICK ( cCode := oCod:code, oDlu:end( ) ) UPDATE
oLbu1:setoDBF( oCod )
add column to oLbu1 header "Code" data oCod:code ALIGN 0,1 size 150 ORDER "erfcod"
add column to oLbu1 Header "Description" data oCod:detail ALIGN 0,1 size 350
oDlu:oClient:= oLbu1
oLbu1:nLineStyle:=0
oLbu1:nHeightCell += 4
oLbu1:nHeightHead += 6
oLbu1:lNoHScroll := .T.
oLbu1:setColor( {1}, {CLR_BROWSETEXT} ) // cell text color
oLbu1:setColor( {4}, {{ CLR_HEADERTOP, CLR_HEADERBOT }} ) // degraded headers background color
oLbu1:setColor( {14}, {{ CLR_HEADERTOP, CLR_HEADERBOT }} ) // degraded headers background color
// Show alternating color in rows
lClrFlag:=.f.
oLbu1:bSkip:={| nRecs | (nRecs:= oCod:skipper( nRecs ), lClrFlag:=if(nRecs/2 = int(nRecs/2), lClrFlag,!lClrFlag), nRecs) }
oLbu1:setColor( { 2 }, { { || if(lClrFlag, CLR_PANE1, CLR_PANE2 ) }} )
Tim Stone
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
http://www.MasterLinkSoftware.com
timstone@masterlinksoftware.com
Using: FWH 19.06 with Harbour 3.2.0 / Microsoft Visual Studio Community 2019
- James Bott
- Posts: 4654
- Joined: Fri Nov 18, 2005 4:52 pm
- Location: San Diego, California, USA
- Contact:
Tim,
I thought we had solved the flickering problem?
The slower loading is due to the fact that it has all the additional features that you like. If all those features were added to TWBrowse then I'm sure it would be just as slow. If you look at the size of the PRGs, TWBrowse is 68K and TSBrowse is 273K (and that is not counting the other modules for columns, etc.).
You can use alternating row colors with TWBrowse by defining a bSkip block. Here is an example using a database object.
The above works with or without indexes and/or filters. Granted it would be nice to have this capability built into TWBrowse. Adjustable line heights would also be a welcome addition, as would header gradient colors. However, making it cell oriented would slow it down considerably.
James
I thought we had solved the flickering problem?
The slower loading is due to the fact that it has all the additional features that you like. If all those features were added to TWBrowse then I'm sure it would be just as slow. If you look at the size of the PRGs, TWBrowse is 68K and TSBrowse is 273K (and that is not counting the other modules for columns, etc.).
You can use alternating row colors with TWBrowse by defining a bSkip block. Here is an example using a database object.
Code: Select all
lClrFlag:=.f.
oLbx:bSkip:={| nRecs | (nRecs:= ::oInvmast:skipper( nRecs ), lClrFlag:=if(nRecs/2 = int(nRecs/2), lClrFlag,!lClrFlag), nRecs) }
oLbx:nClrPane := { || if(lClrFlag, rgb(255,255,235), rgb(192,208,179)) }
James