General suggestions, in preparation for a text-mode array navigator

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

HGAutomator
Posts: 202
Joined: Thu Jul 16, 2020 5:42 pm
DBs Used: DBF

Re: General suggestions, in preparation for a text-mode array navigator

Post by HGAutomator »

"Why Harbour?"

Why do Harbour for anything? Because we love the language and would like to add features in our native environment.

"Why do you have to show the ENTIRE TreeWiew?"

Not necessary to show the entire directory tree. Sending a specific directory as a function is fine. But sometimes, we'll want to send C:\ or F:\.

"You can select only the folder you want to see with:

GetFolder ([<cTitle>], [<cInitPath>], [<cInvalidDataMsg>], [<lNewFolderButton>], [<lIncludeFiles>], [<nCSIDL_FolderType>], [<nBIF_Flags>]) -> cSelectedName"

Not interested in a Win component.

I wanted to see it in TEXT mode, like Xtree Gold or ZTreeWin or the tree component in Far Manager https://www.farmanager.com.

But I'm putting this project aside, because it would probably take too long to put in the all needed features.


"and from there do what you want with the content ..."

Anything we want, including customized features.

So for example, we'd want to use a Text-Mode treeview to build a folder-based pim which would automatically carry To-Do lists of UnFinished items from the previous day to the current day.

We would also want to press ENTER on a file with a specific extension, and it would run a batch file with the selected file as a parameter, and do some pre-processing before viewing or opening or executing the selected file.

And we'd want to do the same things - Copying, Moving, Creating Directories, quickly viewing contents - that we would do with e.g. Harbour Commander or a standard File Manager.

We might also configure it as an XML or Json or EDN viewer.
HGAutomator
Posts: 202
Joined: Thu Jul 16, 2020 5:42 pm
DBs Used: DBF

Re: General suggestions, in preparation for a text-mode array navigator

Post by HGAutomator »

Minor changes to Lotus_Menu(), backing out some changes to the original SLOTUSMENU() from Super.lib, in order to return to the menu - as opposed to exiting - after pressing <ENTER>.

We will need to make changes to <ESC> key handling. The original routine assumed the tree structure was already given, and static, as opposed to generated on-the-fly by navigating directories.

So in the original code, ESC in effect popped the parent array of the current subarray, off a stack. We can't do exactly the same thing here, while navigating subfolders and parent folders. Unless of course we build more of the directory tree, ahead of time.

Code: Select all

FUNCTION Lotus_Menu(nTop,nLeft,nbottom,nRight,Options_a,lBox,lSaveRest,lReset)
LOCAL oTb,cBox,nColumn
LOCAL nTbTop,nTbLeft,nTbBottom,nTbRight,nWidth
LOCAL expReturn := 0
LOCAL nLastkey,cLastkey,nFirstLetter
LOCAL nMouseR, nMouseC
Local Col_n := 0


lBox      := iif(lBox#nil,lBox,.f.)
lSaveRest := iif(lSaveRest#nil,lSaveRest,.f.)
lReset    := iif(lReset#nil,lReset,.f.)
if lBox
  nBottom  := nTop+3
  nTbTop   := nTop+1
  nTbLeft  := nLeft+1
  nTbRight := nRight-1
else
  nBottom  := nTop+1
  nTbTop   := nTop
  nTbLeft  := nLeft
  nTbRight := nRight
endif
if lSaveRest
  if lBox
    cBox := Makebox(nTop,nLeft,nBottom,nRight)
  else
    cBox := Savescreen(nTop,nLeft,nBottom,nRight)
  endif
ELSEIF lBox
    Makebox(nTop,nLeft,nBottom,nRight)
endif
nWidth    := nTbRight-nTbLeft+1
if len(Stack_a)=0
  Current_a  := Options_a
endif
oTb := BuildTb(nTbTop,nTbLeft,nTbTop,nTbRight,nWidth)
oTb:colpos := Element_n

while .t.
  dispbegin()
  while !oTb:stabilize()
  end
  if Current_a[oTb:colpos,2]#nil
    @nTbTop+1,nTbLeft say padr(Current_a[oTb:colpos,2],nWidth)
  else
    scroll(nTbTop+1,nTbLeft,ntbTop+1,nTbRight,0)
  endif
  dispend()

  nMouseR := 0; nMouseC := 0
  nLastKey := rat_event(0,.f.,.f.,@nMouseR,@nMouseC)

  do case

	// ENTER on a folder, will enter that folder.
	// ENTER on a filename, will exit.
  case nLastKey == K_ENTER
    if valtype(Current_a[oTb:colpos,3])=="A"
      aadd(Stack_a,{Current_a,oTb:colpos})
      Current_a := Current_a[oTb:colpos,3]
      oTb := BuildTb(nTbTop,nTbLeft,nTbTop,nTbRight,nWidth)
      oTb:colpos := 1
    elseif valtype(Current_a[oTb:colpos,3])=="B"
    	Col_n := oTb:colpos
    	// expReturn := eval(Current_a[oTb:colpos,3], Col_n )
    	eval(Current_a[oTb:colpos,3], Col_n )
			// Return expReturn
    else
      expReturn := Current_a[oTb:colpos,3]
      exit
    endif
  case nLastKey == K_FORWARD_SLASH      // Popup menu
  	Load_Program_Menu( oTb )
		expReturn := Current_a[oTb:colpos,3]
		Return expReturn

  case nLastKey == K_ESC 	// Back
    if len(Stack_a)>0
      Current_a := atail(Stack_a)[1]
      oTb := BuildTb(nTbTop,nTbLeft,nTbTop,nTbRight,nWidth)
      oTb:colpos :=  atail(Stack_a)[2]
      aSize(Stack_a,len(Stack_a)-1)
    else
      exit
    endif


  case nLastKey == K_LEFT     // allow movement (left)
     IF oTb:colpos > 1
       oTb:left()
     ELSE
       oTb:colpos  := len(Current_a)
       oTb:refreshall()
     ENDIF
  case nLastKey == K_RIGHT    // allow movement (right)
     IF oTb:colpos < len(Current_a)
       oTb:right()
     ELSE
       oTb:colpos  := 1
       oTb:refreshall()
     ENDIF
  CASE (cLastkey := upper(chr(nLastkey)))$"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
     if cLastkey == upper(left(Current_a[oTb:colpos,1],1))
       keyboard chr(13)
     elseif (nFirstLetter := ascan(Current_a,{|e|e[1]#nil.and.upper(left(e[1],1))==cLastKey },oTb:colpos+1)) > 0 ;
        .or. (nFirstLetter := ascan(Current_a,{|e|e[1]#nil.and.upper(left(e[1],1))==cLastKey },1,oTb:colpos)) > 0
       oTb:colpos  := nFirstLetter
       oTb:refreshall()
     endif
  case MBRZMOVE(oTb,nMouseR,nMouseC)
     keyboard chr(K_ENTER)
  case MBRZCLICK(oTb,nMouseR,nMouseC)
     keyboard chr(K_ENTER)
  endcase
end
Element_n := oTb:colpos
if lSaveRest
  if lBox
    unbox(cBox)
  else
    restscreen(nTop,nLeft,nBottom,nRight,cBox)
  endif
endif
if lReset
  Lotus_Clear()
endif
return expReturn

//----------------------------------------------------------------------
FUNCTION Lotus_Clear
Stack_a := {}
Element_n := 1
return nil
//-----------------------------------------------------------------
static function BuildTb(ntop,nLeft,nbottom,nRight,nWidth)
local oTb,nColumn
local ntotWidth := ttlwidth()
scroll(nTop,nLeft,nBottom,nRight,0)
if ntotWidth >= nWidth
  oTb := tbrowsenew(nTop,nLeft,nbottom,nRight)
else
  oTb := tbrowsenew(nTop,nLeft,nbottom,nLeft+nTotWidth-1)
endif
for nColumn = 1 to len(Current_a)
  oTb:addcolumn(tbColumnNew(nil,lmblock(nColumn)))
next
otb:skipblock := {|n|0}
return oTb

//-----------------------------------------------------------------
static function lmblock(i)
return {||Current_a[i,1]}


//-----------------------------------------------------------------
static function ttlwidth
local nWidth := 0
aeval(Current_a,{|e|nWidth+=len(e[1])+1})
return nWidth



// TODO
Function Load_Program_Menu( oTb )
Local Program_Menu_a := {}


Program_Menu_a := { { "File", "New Open Exit", { || Alert( "File menu" ) } }, ;
										{ "Preview", "As Text  As Binary  As OutLine", { || Alert( "Preview menu" ) } } ;
										 }

SLOTUSMENU(23,0,24,MaxCol(),Program_Menu_a,.t.,.t.,.t.)


Return Nil

HGAutomator
Posts: 202
Joined: Thu Jul 16, 2020 5:42 pm
DBs Used: DBF

Re: General suggestions, in preparation for a text-mode array navigator

Post by HGAutomator »

Update, 11/01/2021

Tweaked the interface for ESC key handling.

We now have a basic, no-frills horizontal folder navigator.

We'll do some cleanup ; add some comments ; and add some features with buttons or hot keys or some other trigger object we haven't thought of yet.

Thanks everyone for the suggestions, and for the assistance with some of the functions I asked about.

Image
Attachments
LotusMenu.zip
(715.67 KiB) Downloaded 78 times
Horizontal_Menu_Directory_Navigator_20211101.jpg
Horizontal_Menu_Directory_Navigator_20211101.jpg (411.2 KiB) Viewed 717 times
HGAutomator
Posts: 202
Joined: Thu Jul 16, 2020 5:42 pm
DBs Used: DBF

Re: General suggestions, in preparation for a text-mode array navigator

Post by HGAutomator »

It's gonna be a few weeks or more, before the next update. Lots of refactoring & simplifying to do.

The code is a mess, obviously, and is using Superlib's horizontal menu routine in a different way than originally intended. This was just proof-of-concept.

Fortunately, it's a very small code base overall, and hopefully we can keep it that way.

Aside from code changes, we'll get started on the docs this week.
Post Reply