I want to offer a debug function _ArrayView("Array"), which accepts a string with the name of a one-dimensional or two-dimensional index array and creates a table corresponding to this array. This way of passing an array using a string containing its name is connected
only with the desire to put this name in the header of the table.
Array indexing does not necessarily start from 1, but can be any, even negative, and also have gaps. The array element with indices (i, j) is placed in the table in row i and column j.
Table columns have a minimum width in order to display their contents. But table elements that are longer than MaxColumnWidth are cut off and end with an ellipsis.
If the table does not fit in the window, then it can be moved using the Up, Down, Left, Right, Left+Up, Right+Down arrows. The Numpad0 key returns the table to its original (before moving) state.
It is convenient to set a hot key, according to which the _ArrayView("Array") function call is inserted into the tested program.
global TableWidth ; Number of table columns
global TableHight ; Number of table rows
global ColumnInterval ; Interval between columns
global MaxColumnWidth ; Maximum table column width
global ColumnsWidth ; Array of column widths
global FirstColumnWidth ; Auxiliary column width containing row indices
global MinColumn ; The index of the leftmost (first) column. Can be negative
global Rows ; Array of indexes numbering table rows
global ArrView ; Control name Text
global Text ; Text displayed by this control
global Tip ; Name of the tooltip
_ArrayView(ArrName) {
MaxColumnWidth := 15, FirstColumnWidth := 4, ColumnInterval := 3 ; Table display options described above
Array := %ArrName%
Text := Arr2string(Array)
Gui Color, Black
Gui Font, s10 cWhite, Consolas
Gui Add, Text, Left vArrView, %Text%
Gui Add, Text, cRed gTip w30 x2 y5, Tip
Gui +AlwaysOnTop
Gui Show, Autosize, Array %ArrName%
pause
return
}
Tip() {
static Switcher := 1
if (Switcher) {
Txt = Navigation (if the table is not fully visible)`n Arrows: Left, Right, Up, Down`nLeft+Up
, Right+Down.`nTo starting position: Numpad0`nTable exit: Esc
ToolTip %Txt%, 60, -150
Switcher := 0
}else{
ToolTip
Switcher := 1
}
}
/* The function returns a string to display the argument array as a table
*/
Arr2string(Array) {
If !IsObject(Array[Array.MinIndex()]){ ; Checking if an array is one-dimensional. If yes, then it is for uniformity
aTemp := [] ; turns into a multidimensional array with a single row
aTemp[1] := Array
Array := aTemp
}
Rows := [] ; Array of indexes numbering rows
for key in Array
Rows[A_Index] := key
TableHight := Rows.length()
MinColumns := [] ; Arrays of minimum (left) indices in each row
MaxColumns := [] ; Samу for maximum (right) indices in each row
Loop % TableHight {
Row := Row(A_Index)
MinColumns[A_Index] := Array[Row].MinIndex()
MaxColumns[A_Index] := Array[Row].MaxIndex()
}
MinColumn := Min(MinColumns*) ; Index of the leftmost (first) column of the table
MaxColumn := Max(MaxColumns*) ; Same for the rightmost (last) column of the table
TableWidth := MaxColumn - MinColumn + 1
ColumnsWidth := [] ; Массив ширин столбцов таблицы
Loop % TableWidth {
Column := Column(A_Index)
CellsWidth := []
Loop % TableHight {
Row := Row(A_Index)
CellsWidth[A_Index] := StrLen(Array[Row, Column])
}
; The minimum required column width is set, but not more than the maximum value common to all columns
ColumnsWidth[Column] := Min(Max(CellsWidth*), MaxColumnWidth)
}
HeadLine := Spaces(FirstColumnWidth) ; Additional line containing column numbers
Loop % TableWidth {
Column := Column(A_Index)
if !ColumnsWidth[Column] ; Empty column numbering is not displayed
continue
HeadLine .= Column Spaces(ColumnsWidth[Column] + ColumnInterval - StrLen(Column))
}
TableText := HeadLine "`r`n"
; Элементы таблицы собираются в одну строку
loop % TableHight {
Row := Row(A_Index)
if (TableHight = 1) ; If the displayed array is one-dimensional
TableText .= Spaces(FirstColumnWidth)
else
TableText .= Row Spaces(FirstColumnWidth - StrLen(Row))
loop % TableWidth {
Column := Column(A_Index)
if !ColumnsWidth[Column] ; Empty columns are not displayed
continue
TableText .= Normalize(Array[Row, Column], ColumnsWidth[Column])
}
TableText .= "`r`n"
}
return TableText
}
/*The function adds spaces to the elements of the array or trims them so that they have the size given by the second argument.
*/
Normalize(String, Size) {
if (Strlen(String) >= MaxColumnWidth)
String := SubStr(String, 1, MaxColumnWidth - 3) "..."
return SubStr(String .= Spaces(Size + ColumnInterval), 1, Size) Spaces(ColumnInterval)
}
/* The next two functions are for row/column indexes that do not start at 1 and have gaps. They match
* the ordinal number of the row/column is the value of its index in the array.
*/
Row(Index) {
return Rows[Index]
}
Column(Index) {
return Index + MinColumn - 1
}
Spaces(N) {
Spaces := ""
Loop % N
Spaces .= " "
return Spaces
}
/* The function removes the top rows and/or left columns to shift the table
*/
CropTable(Raws2Del, Columns2Del) {
CurText := Text
CurText := RegExReplace(CurText, "(.*`r`n)(?:.*`r`n){" Raws2Del "}((?:.*`r`n)*)", "$1$2")
Symbols2Del := []
loop % Columns2Del {
Symbols2Del += ColumnsWidth[A_Index] + ColumnInterval
}
CurText := RegExReplace(CurText, "im)^(.{" FirstColumnWidth "}).{" Symbols2Del "}(.*`r`n)", "$1$2")
GuiControl,, ArrView, %CurText%
GuiControl,, Tip, Tip ; Recalling the Tip function so that the Tip button is not covered by the table
}
/*The function shifts the table h columns to the left and k rows up
*/
ShiftTable(h,k) {
SetNumLockState, On
static Raws2Del := 0
static Columns2Del := 0
if Raws2Del + h < 0 or Raws2Del + h >= TableHight { ; Запрет выхода за пределы таблицы по вертикали
return
}
Raws2Del += h
if Columns2Del + k < 0 or Columns2Del + k >= TableWidth { ; Запрет выхода за пределы таблицы по горизонтали
return
}
Columns2Del += k
if (h = 0 and k = 0) { ; Возвращение таблице исходного вида (до перемещений
Raws2Del := 0
Columns2Del := 0
}
CropTable(Raws2Del, Columns2Del)
}
Right:: ShiftTable(0, -1)
Left:: ShiftTable(0, 1)
Down:: ShiftTable(-1, 0)
Up:: ShiftTable(1, 0)
Left & Up:: ShiftTable(1, 1)
Right & Down:: ShiftTable(-1, -1)
Numpad0:: ShiftTable(0, 0)
GuiClose:
GuiEscape:
ToolTip
suspend
Gui Destroy
pause