A common goal for a developer is to make the User Interface as easy to understand as possible. One UI widget that can make the complex look simple is a popup menu with icons. This Tech Tip will demonstrate how to create a popup menu that transforms a path string into a popup with icons.
It is poor to assume that the end user will understand even simple programming structures such as a file path string when presented to them, especially a user used to a graphical interface instead of a command line interface. The method below demonstrates how to take a path string and present with as a popup with icons representing the different parts of the path: the file, the folders, and the root as shown in the image below.
The source code to methods called by this method follow it.
If (True) If (False) Begin SQL /* MENU_PathnamePopup ($Type_L;$Path_T;$Prompt_T) -> Menu Choice Purpose: Present a popup of the path tree and prompt $0 - TEXT - Menu Choice $1 - Longint - Path type, directory or document $2 - TEXT - The path string $3 - TEXT - Prompt */ End SQL End if C_TEXT($MethodName_T) $MethodName_T:=Current method name //================== Declare Variables ================= //method_parameters_declarations C_TEXT($0;;$Choice_T) C_LONGINT($Type_L;$1) C_TEXT($Path_T;$2) C_TEXT($Prompt_T;$3) //--------------------------------------------------------- //method_wide_constants_declarations //--------------------------------------------------------- //local_variable_declarations C_LONGINT($Ndx;$SOA;$RIS;$Params_L;$OS_L) C_TEXT($MenuRef_T;$Delim_T;$Icon_T) End if //================= Initialize and Setup ================= $Params_L:=Count parameters If ($Params_L#3) ASSERT(False;"Parameter conunt not equal to 3!") Else $Type_L:=$1 $Path_T:=$2 $Prompt_T:=$3 //================= Method Actions ================= $OS_L:=Pathname_OSType ($Path_T) If ($OS_L=Windows) $Delim_T:="\\" Else $Delim_T:=":" End if $RIS:=STR_CountFields ($Path_T;$Delim_T) If ($Prompt_T#"") ARRAY TEXT($Items_aT;$RIS+2) Else ARRAY TEXT($Items_aT;$RIS) End if If ($OS_L=Windows) // Match regex comand used in STR_Parse method has problems // with Window folder separater as used in this variable. // substituting a tab character and changing the delimiter // works around the issue. // ( $Path_T:=Replace string($Path_T;$Delim_T;"\t") $Delim_T:="\t" // ) End if $Items_aT:=0 For ($Ndx;$RIS;1;-1) $Items_aT:=$Items_aT+1 $Items_aT{$Items_aT}:=STR_Parse ($Path_T;$Ndx;$Delim_T) If ($Items_aT=$RIS) $Items_aT{$RIS}:=Replace string($Items_aT{$RIS};":";"") End if End for If ($Prompt_T#"") $Items_aT:=$Items_aT+1 $Items_aT{$Items_aT}:="(-" // Menu separator line $Items_aT:=$Items_aT+1 $Items_aT{$Items_aT}:=$Prompt_T End if $MenuRef_T:=Create menu For ($Ndx;1;$RIS) APPEND MENU ITEM($MenuRef_T;$Items_aT{$Ndx}) If ($Ndx=$RIS) If ($OS_L=Windows) SET MENU ITEM ICON($MenuRef_T;$Ndx;"File:Win_HD_icon.png") Else SET MENU ITEM ICON($MenuRef_T;$Ndx;"File:Mac_HD_icon.png") End if Else $Icon_T:=MENU_Icon ($OS_L;$Items_aT{$Ndx}) SET MENU ITEM ICON($MenuRef_T;$Ndx;$Icon_T) End if End for If ($Prompt_T#"") APPEND MENU ITEM($MenuRef_T;$Items_aT{$Items_aT-1}) // Prompt menu and value to be returned by the choice // ( APPEND MENU ITEM($MenuRef_T;$Items_aT{$Items_aT}) SET MENU ITEM PARAMETER($MenuRef_T;-1;String($Items_aT{$Items_aT})) // ) End if // Present the popup menu to the user // ( $Choice_T:=Dynamic pop up menu($MenuRef_T;"") // ) // Clear the menu from memory // ( RELEASE MENU ($MenuRef_T) // ) End if //================= Clean up and Exit ================= $0:=$Choice_T |
The method below, Pathname_OSType, will test the string and return its native OS type.
If (True) If (False) Begin SQL /* Pathname_OSType ($Path_T) -> OSType Purpose: Given a path string, determine what is its native OS $0 - Longint - purpose $1 - TEXT - purpose */ End SQL End if C_TEXT($MethodName_T) $MethodName_T:=Current method name //================= Declare Variables ================= //method_parameters_declarations C_LONGINT($0) C_TEXT($Path_T;$1) //-------------------------------------------------------------------------------- //method_wide_constants_declarations //-------------------------------------------------------------------------------- //local_variable_declarations C_LONGINT($Pos_L) C_TEXT($RegExPat_T) C_BOOLEAN($Found_B) End if //================= Initialize and Setup ================= $Path_T:=$1 // msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx // // Valid start for Windows absolute path strings such as: // ([a-zA-Z]:\\\\) - A disk designator with a backslash, e.g. "C:\" or "d:\" // (\\\\) - A UNC name of any format, starts with two backslash characters ("\\"). // ( $RegExPat_T:="(([a-zA-Z]:\\\\)|(\\\\))" // ) //================= Method Actions ================= $Found_B:=Match regex($RegExPat_T;$Path_T;1;$Pos_L) If ($Found_B & ($Pos_L=1)) $0:=Windows Else $0:=Mac OS End if |
The method below, STR_CountFields, will how many delimited elements are in the string.
If (True) If (False) Begin SQL /* STR_CountFields($Buf_T;$Delim_T) Purpose: Count how many fields exist in a conpacted string $1 - TEXT - Contains the String to be tested $2 - TEXT - Contains the Delimiter to test with /* End SQL End if C_TEXT($MethodName_T) $MethodName_T:="CVT_CountFields" //===================== Declare Variables ================= //method_parameters_declarations C_TEXT($Buf_T;$1) C_TEXT($Delim_T;$2) //-------------------------------------------------------------------------------- //method_wide_constants_declarations //-------------------------------------------------------------------------------- //local_variable_declarations C_LONGINT($Ndx;$Len;$Cnt) End if //====================== Initialize & Setup ================================ $Buf_T:=$1 $Delim_T:=$2 $Cnt:=0 $Len:=Length($Buf_T) //======================== Method Actions ================= If ($Len>0) $Ndx:=Position($Delim_T;$Buf_T) // Count the record delimiters in the chunk. While ($Ndx#0) If ($Len>0) $Buf_T:=Substring($Buf_T;$Ndx+1) $Cnt:=$Cnt+1 $Ndx:=Position($Delim_T;$Buf_T) $Len:=Length($Buf_T) End if End while If ($Len>0) $Cnt:=$Cnt+1 End if End if //======================== Clean up & Exit ================================= $0:=$Cnt |
The method below, STR_Parse, will return Nth delimited element from a string.
If (True) If (False) Begin SQL /* STR_Parse (SourseText_T; OccuranceWanted_L{{; Delimiter_T}; Truncate_P}) -> String Purpose: To return nth element from a delimited string $1 - TEXT - string to search in $2 - LONGINT - integer number of times to locate character $3 - STRING - (optional) string, the character to search for $4 - POINTER - (optional) pointer - pointer to initial string to allow truncation (Destructive parsing) /* End SQL End if C_TEXT($MethodName_T) $MethodName_T:=Current method name //===================== Declare Variables ================= //method_parameters_declarations C_TEXT($0;$String;$1;$Result) C_LONGINT($Wanted;$2) C_STRING(80;$Search;$3) C_POINTER($4;$Truncate) // 12/20/96 //-------------------------------------------------------------------------------- //method_wide_constants_declarations //-------------------------------------------------------------------------------- //local_variable_declarations C_LONGINT($Ndx;$SOA;$Pos_L;$Len_L;$Params_L) C_BOOLEAN($Success) End if //====================== Initialize and Setup ================================ $String:=$1 $Wanted:=$2 // the number of the character to find $Result:="" //======================== Method Actions ================= If (($String#"") & ($Wanted>0)) $Params_L:=Count parameters If ($Params_L=2) // if this is looking just for tabs $Search:="\t" Else // assign passed string $Search:=$3 If ($Params_L=4) $Truncate:=$4 // pointer to value to truncate End if End if $SOA:=1 $Pos_L:=1 $Ndx:=STR_CountFields ($String;$Search) If ($Ndx>=$Wanted) //======================== Method Actions ================= For ($Ndx;1;$Wanted) $Success:=Match regex($Search;$String;$SOA;$Pos_L;$Len_L) Case of : ($Success) & ($Ndx=$Wanted)) If ($Params_L<4) $Result:=Substring($String;$SOA;$Pos_L-$SOA) Else // replace the incomming string with the truncated version (found removed) $Truncate->:=Substring($String;1;$SOA) End if : ($Ndx=$Wanted) If ($Params_L<4) $Result:=Substring($String;$SOA) Else // replace the incomming string with the truncated version (found removed) $Truncate->:=Substring($String;1;$SOA) End if Else $SOA:=$Pos_L+$Len_L End case End for //======================== Clean up and Exit ================================= End if End if $0:=$Result |
The method below, MENU_Icon, will return the path string to the icon.
If (True) If (False) Begin SQL /* MENU_Icon ( OS_L; File Suffix {; "*" }) -> $Path_L Purpose: Return the path to the Icon to be included in a Menu item or to be loaded using READ PICTURE FILE $0 - TEXT - File path to the icon $1 - LONGINT - OS, Windows or Mac OS $2 - TEXT - File suffix $3 - TEXT - Option param */ End SQL End if C_TEXT($MethodName_T) $MethodName_T:=Current method name //===================== Declare Variables ================= //method_parameters_declarations C_TEXT($0;$Path_T) C_LONGINT($OS_L;$1) C_TEXT($Suffix_T;$2) //-------------------------------------------------------------------------------- //method_wide_constants_declarations //-------------------------------------------------------------------------------- //local_variable_declarations C_LONGINT($Ndx;$Params_L) End if //====================== Initialize and Setup ================================ $Path_T:="" $Params_L:=Count parameters If (Asserted(($Params_L>1) & ($Params_L<4);"Bad param count")) $OS_L:=$1 $Suffix_T:=$2 $Suffix_T:=Pathname_Suffix ($Suffix_T) //======================== Method Actions ================= Case of : ($Suffix_T="") If ($OS_L=Windows) $Path_T:="File:Win_Folder_icon.png" Else $Path_T:="File:Mac_Folder_icon.png" End if : ($Suffix_T=".4DD") $Path_T:="File:4DD.png" : ($Suffix_T=".4DIndx") $Path_T:="File:4DIndx.png" : ($Suffix_T=".4DIndy") $Path_T:="File:4DIndy.png" : ($Suffix_T=".4DMatch") $Path_T:="File:4DGeneric.png" : ($Suffix_T=".4BK") $Path_T:="File:4DGeneric.png" : ($Suffix_T=".4BL") $Path_T:="File:4DGeneric.png" : ($Suffix_T=".4DSyncData") $Path_T:="File:4D_Server.png" : ($Suffix_T=".4DSyncHeader") $Path_T:="File:4D_Server.png" : ($Suffix_T=".BLOB") $Path_T:="File:4D_BLOB.png" Else $Path_T:="File:Generic-Document-icon.png" End case If ($Params_L=3) // When using READ PICTURE FILE "File:" must be replaced with absolute path // ( $Path_T:=Replace string($Path_T;"File:";Get 4D folder(Current Resources folder)) // ) End if //======================== Clean up and Exit ================================= End if $0:=$Path_T |
The method below, Pathname_Suffix, will return the suffix on the file name or "" on a path.
If (True) If (False) Begin SQL /* Pathname_Suffix ( $Path_T ) -> $Suffix_T Written by Charles Vass - 01/25/2012, 10:46 Purpose: Return the suffix off a file path or an empty string $0 - TEXT - File suffix or empty string $1 - TEXT - Pathname */ End SQL End if C_TEXT($MethodName_T) $MethodName_T:=Current method name //===================== Declare Variables ================================== //method_parameters_declarations C_TEXT($0;$Suffix_T) C_TEXT($Path_T;$1) //-------------------------------------------------------------------------------- //method_wide_constants_declarations //-------------------------------------------------------------------------------- //local_variable_declarations C_LONGINT($Ndx;$SOA) End if //====================== Initialize and Setup ================================ $Path_T:=$1 //======================== Method Actions ================================== $Ndx:=STR_PositionR (".";$Path_T) If ($Ndx>0) $Suffix_T:=Substring($Path_T;$Ndx) End if //======================== Clean up and Exit ================================= $0:=$Suffix_T |
The method below, STR_PositionR, preforms the Position function from the end of the string.
If (True) If (False) Begin SQL /* STR_PositionR Purpose: Position of target string from the right $0 - LONGINT - Position $1 - TEXT - What to find $2 - TEXT - Source string /* End SQL End if C_TEXT($MethodName_T) $MethodName_T:=Current method name //===================== Declare Variables ================================== //method_parameters_declarations C_LONGINT($0;$PosLast_L) C_TEXT($1;$Find_T) C_TEXT($2;$String_T) //-------------------------------------------------------------------------------- //method_wide_constants_declarations //-------------------------------------------------------------------------------- //local_variable_declarations C_LONGINT($PosNext_L) C_TEXT($Marker_T) End if //====================== Initialize and Setup ================================ $Find_T:=$1 $String_T:=$2 //======================== Method Actions ================================== $Marker_T:=Char(1)*Length($Find_T) If ($Find_T=$Marker_T) $Marker_T:=Char(2)*Length($Find_T) End if $PosLast_L:=0 Repeat $PosNext_L:=Position($Find_T;$String_T) If ($PosNext_L>0) $PosLast_L:=$PosNext_L $$String_T:=Replace string($$String_T;$Find_T;$Marker_T;1) End if Until ($PosNext_L=0) //======================== Clean up and Exit ================================= $0:=$PosLast_L |