Two column dialog

Is it possible to have a two vertical column dialog with Shane’s Dialog Toolkit Plus?

Cheers

Yes, you just have to set the coordinates accordingly, so they don’t overlap.

Awesome thanks Shane couldn’t work out the syntax but the extra motivation of knowing it was possible was enough to work it out.

Would you mind sharing your solution?

Here is a fragment from one of my scripts:

set theTopCol2 to theTop
-- "Album will have name of form Bach: Cello Suite No. 4: Rostropovich 1995"
set {albumFieldLabel, theTop} to create label albumFieldLabel bottom theTop + sectionSpaceDepth left inset 0 max width exampleAlign aligns right aligned control size small size without multiline
set {albumExampleLabel, theTop} to create label albumExampleLabel bottom theTopCol2 + sectionSpaceDepth left inset exampleAlign max width accViewWidth - exampleAlign aligns left aligned control size small size without multiline

Here is an example of how I created a two column view. Probably not the best solution but it seems to work.

use scripting additions
use script "Dialog Toolkit Plus" version "1.1.0"

set accViewWidth to 650
set {theButtons, minWidth} to create buttons {"Cancel", "OK"} button keys {"", "2", "1", ""} default button 1 cancel button 2
if minWidth > accViewWidth then set accViewWidth to minWidth -- make sure buttons fit
set {rightField, theTop} to create field "" placeholder text "Enter your right text here" bottom 0 field width accViewWidth / 2 extra height 60 left inset accViewWidth / 2 + 10 with accepts linebreak and tab
set {leftField, theTop} to create field "" placeholder text "Enter your left text here" bottom 0 field width accViewWidth / 2 extra height 60 with accepts linebreak and tab
set {boldLabel, theTop} to create label "Here is the top bold label" bottom theTop + 20 max width accViewWidth control size regular size
set {buttonName, controlsResults} to display enhanced window "Two-column" acc view width accViewWidth + 10 acc view height theTop acc view controls {leftField, rightField, boldLabel} buttons theButtons active field leftField initial position {0, 0} with align cancel button

@JMichaelTX Here is my New Year’s present to you. This script is overkill for you but creates tables from label. I use it for a two-column layout exclusively. I had a dictionary but ran into conflicts with the Dialog Toolkit overlapping terminologies. I haven’t fully tested this but it seems to work well. It has an embedded test harness that you can play with.

-- Utilities for scripts by Shane Stanley
--	Created by: Jonathan Nebeker on: 12/29/21
--	Copyright © 2022 Jonathan Nebeker, All Rights Reserved
--  Anyone is free to use, distribute, and modify this code at their own risk. The copyright holder provides this work an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
--
use AppleScript version "2.4" -- Yosemite (10.10) or later
--use framework "Foundation"
--use scripting additions
use script "Dialog Toolkit Plus" version "1.1.2"

(*on run
	_testDTcreateTableFromLabels()
end run*)

on _testDTcreateTableFromLabels()
	--v2021-12-31
	local columnL, maxWidthL, alignsL, theBottom, leftInset, columnGutter, controlSize, boldType, tightColumns, lableList, theTop, totalWidth
	set columnL to {¬
		"left line 1" & return & "left 2" & return & "left line three", ¬
		"right line 1" & return & "right 2, which is very very long and gives me a headache" & return & "right line three" & return & "right 4", ¬
		1}
	set leftInset to 0
	set theBottom to 0
	set maxWidthL to {150, 150, 75}
	set columnGutter to 50
	set alignsL to {right aligned, left aligned, center aligned}
	set controlSize to small size
	set boldType to false
	set tightColumns to true
	
	--set {columnL, actualWidthL} to my DTalignTableForLabels(columnL, maxWidthL, controlSize, boldType)
	--set {leftLabel, rightLabel} to align table for labels {leftLabel, rightLabel} max widths {150, 150} control size small size without bold type
	set {lableList, theTop, totalWidth} to DTcreateTableFromLabels(columnL, leftInset, theBottom, maxWidthL, columnGutter, alignsL, controlSize, boldType, tightColumns)
	
	set allControls to lableList
	try
		set {theButtons} to create buttons {"Cancel", "OK"} cancel button 1 default button 2 with equal widths
		set {buttonName, controlsResults} to display enhanced window "Left block right aligned" acc view width totalWidth acc view height theTop acc view controls allControls buttons theButtons giving up after 240 with align cancel button
	end try
	
end _testDTcreateTableFromLabels

on DTcreateTableFromLabels(columnL, leftInset, theBottom, maxWidthL, columnGutter, alignsL, controlSize, boldType, tightColumns)
	-- on create table from labels columnL left inset leftInset: 0 bottom theBottom max widths maxWidthL column gutter columnGutter : 0 aligns alignsL : missing value control size controlSize : small size bold type boldType : false tighten columns tightColumns : false
	-- revised 2021-12-30
	-- Purpose: creates labels in a table of aligned rows. If actualWidthL is supplied, uses the lesser of maxWidthL and actualWidthL for each column to suck up space
	-- Parameters:
	-- columnL = A list of at least two lists or of at least two strings with embedded carriage returns or line feeds. Each sublist or string delimited by a return or line feed is a table cell.
	-- leftInset = An integer denoting how much to inset the control from the left of the accessory view. Default is 0.
	-- theBottom = An integer denoting the distance from the bottom of the accessory view to the bottom of the control.
	-- maxWidthL = A list of at least two integers that indicate the maximum width of each column. An interger or the last item of partial list will be carried forward.
	-- columnGutter = An integer denoting how much space to insert between columns. Default is 0.
	-- alignsL = A list of of DT alignment values denoting the text alignment of label: left aligned/right aligned/center aligned for each column. An single DT alignment value or the last item of partial list will be carried forward. Default is left aligned.
	-- controlSize = A DT property string denoting the DT line size Type size: regular size/small size/mini size. Default is small size.
	-- boldType = A boolean denoting whether to use bold type. Default is false.
	-- tightColumns = a boolean denoting whether  to suck up empty space between columns based on actual line wraps versus max widths. Default is false.
	--Requirements:
	--must have use statement for Dialog Toolkit Plus in this script file
	
	-- Initialize, clean and check for fatal errors
	if columnL's class ≠ list then error "There must be at least two items in column list." number -1700
	try
		set leftInset to leftInset as integer
		set theBottom to theBottom as integer
		set columnGutter to columnGutter as integer
	on error
		error "Left inset, bottom, and column gutter must be an integer or a real number. They are:" & return & leftInset & return & theBottom & return & columnGutter number -1700
	end try
	try
		if maxWidthL's class ≠ list then set maxWidthL to {maxWidthL as integer}
		repeat with i from 1 to columnL's length
			if maxWidthL's length < i then
				set maxWidthL to maxWidthL & ((maxWidthL's item (i - 1)) as integer)
			else
				set maxWidthL's item i to (maxWidthL's item i) as integer
			end if
		end repeat
	on error errMsg number errNum
		error "The list of max widths must contain integers or real numbers." number -1700
	end try
	try
		if alignsL = missing value then
			set alignsL to {left aligned}
		else if alignsL is in {left aligned, right aligned, center aligned} then
			set alignsL to {alignsL}
		end if
		repeat with c from 1 to columnL's length
			if alignsL's length < i then
				set alignsL to alignsL & alignsL's item (i - 1)
			else
				if alignsL's item i is not in {left aligned, right aligned, center aligned} then error "pass" number -1700
			end if
		end repeat
	on error errMsg number errNum
		error "Align list must be left aligned/right aligned/center aligned or have a list of the these value." number -1700
	end try
	if controlSize = regular size then
		set linePointDepth to 16
	else if controlSize = mini size then
		set linePointDepth to 11
	else if controlSize = large size then
		set linePointDepth to 18 --**********?
	else if controlSize = small size or controlSize = missing value then
		set linePointDepth to 14
	else
		error "Control size must be one of regular size/mini size/small size. Small size is default" number -1700
	end if
	if boldType = "" or boldType = missing value then
		set boldType to true
	else if boldType's class ≠ boolean then
		error "Bold type must be boolean, empty string, or missing value." number -1700
	end if
	if tightColumns = "" or tightColumns = missing value then
		set tightColumns to true
	else if tightColumns's class ≠ boolean then
		error "Tighten columns must be boolean, empty string, or missing value ." number -1700
	end if
	set {saveTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {return, linefeed}}
	local linePointDepth, maxRows, columnLrowLineDepthL, maxRowLineDepthL, cRowLineDepthL, singleLineMaxWidthL
	-- Assemble measurements for row numbers and heights
	set maxRows to 0
	set columnLrowLineDepthL to {}
	set maxRowLineDepthL to {}
	set singleLineMaxWidthL to {}
	repeat with c from 1 to columnL's length
		-- Set up column c as list
		if columnL's item c's class = text then
			set columnL's item c to text items of columnL's item c
		else if columnL's item c's class ≠ list then
			set columnL's item c to {(columnL's item c) as text}
		else
			repeat with r from 1 to columnL's item c's length
				set columnL's item c's item r to (columnL's item c's item r) as text
			end repeat
		end if
		-- Update measurement of actual widths for displaying label text all on one line
		set singleLineMaxWidthL to singleLineMaxWidthL & {0}
		max width for labels columnL's item c control size controlSize bold type boldType
		((result) as integer) + 1
		if singleLineMaxWidthL's item c < result then set singleLineMaxWidthL's item c to result
		-- Update identification of most lines in any column
		if columnL's item c's length > maxRows then
			set maxRows to columnL's item c's length
		end if
		-- Update measurement of row line depths
		set cRowLineDepthL to {}
		repeat with r from 1 to columnL's item c's length
			max depth for label (columnL's item c's item r) as text control size controlSize max width maxWidthL's item c bold type boldType
			set the end of cRowLineDepthL to result div linePointDepth
			if r > maxRowLineDepthL's length then
				set maxRowLineDepthL to maxRowLineDepthL & {cRowLineDepthL's item r}
			else
				if cRowLineDepthL's item r > maxRowLineDepthL's item r then set maxRowLineDepthL's item r to cRowLineDepthL's item r
			end if
		end repeat
		set the end of columnLrowLineDepthL to cRowLineDepthL
	end repeat
	-- Update row heights
	repeat with c from 1 to columnL's length
		repeat with r from 1 to maxRows
			-- Add row to column to even it up with others, if needed.
			if columnL's item c's length < r then
				set columnL's item c to columnL's item c & {""}
				set columnLrowLineDepthL's item c to columnLrowLineDepthL's item c & {1}
			end if
			-- Add returns as necessary to even up row line depth
			repeat with i from 1 to (maxRowLineDepthL's item r) - (columnLrowLineDepthL's item c's item r)
				set columnL's item c's item r to (columnL's item c's item r) & return
			end repeat
		end repeat
		-- Convert columns from rows (lists) to text.
		set columnL's item c to (columnL's item c) as text
	end repeat
	
	-- Update column widths and create labels
	local DTlabelDefinitionL, theTop, actualWidthL, leftInsetL
	set {DTlabelDefinitionL, theTop, actualWidthL, leftInsetL} to {{}, 0, {}, {leftInset}}
	repeat with c from 1 to columnL's length
		set {DTlabelDefinitionL, actualWidthL} to {DTlabelDefinitionL & {missing value}, actualWidthL & {missing value}}
		if maxWidthL's item c > singleLineMaxWidthL's item c and tightColumns then set maxWidthL's item c to singleLineMaxWidthL's item c
		set {DTlabelDefinitionL's item c, theTop, actualWidthL's item c} to create label (columnL's item c) bottom theBottom left inset (leftInsetL's item c) max width (maxWidthL's item c) aligns (alignsL's item c) control size controlSize with multiline
		if not tightColumns then set actualWidthL's item c to maxWidthL's item c
		if c ≠ columnL's length then set leftInsetL to leftInsetL & {(leftInsetL's item c) + ((actualWidthL's item c) as integer) + columnGutter}
	end repeat
	set AppleScript's text item delimiters to saveTID
	{DTlabelDefinitionL, theTop, (actualWidthL's item -1) + (leftInsetL's item -1), actualWidthL, leftInsetL}
end DTcreateTableFromLabels

And here is a more compact but less robust version:

on DTcreateSmallFacingLabelValueLabels(columnL, theBottom, maxWidthL)
	-- revised 2022-01-01
	-- Purpose: Creates a pair of facing lables with algined rows even in the right column wraps. The pair alisgn at the first value of maxValueWidthL: the left label aligns right and the right label aligns left. The right label is assumed not to wrap and the left label may wrap. Can handle up to 4 wraps (5 total line depth) in a row.
	-- columnL = A list of two text strings (or lists with text strings) denoting two columns each with return-delimited rows. The number of rows in each column must be equal.
	-- maxValueWidthL = A list of integers that denotes 
	-- Assumes that the labels in column 1 do not wrap
	-- Notes:
	-- 14 = lide depth in points of small size. (Each block of text is 1 more than the line point depth.)
	local notLastReturn, returnsFromZeroL, theTop, actualWidthL
	set {saveTID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {return, linefeed}}
	repeat with c from 1 to 2
		if columnL's item c's class = text then set columnL's item c to columnL's item c's text items
	end repeat
	if columnL's item 1's length ≠ columnL's item 2's length then error "The two columns cannot have a different number of rows denoted by items or delimited by returns or line feeds." number -1700
	set returnsFromZeroL to {"", return, return & return, return & return & return, return & return & return & return}
	repeat with r from 1 to columnL's item 1's length -- only adjust row line depth in right column
		set columnL's item 1's item r to (columnL's item 1's item r) & returnsFromZeroL's item ((max depth for label ((columnL's item 2's text item r) as text) control size small size max width (maxWidthL's item 2)) div 14)
	end repeat
	set actualWidthL to {missing value, missing value}
	set {columnL's item 1, theTop, actualWidthL's item 1} to create label ((columnL's item 1) as text) bottom theBottom left inset 0 max width (maxWidthL's item 1) aligns right aligned control size small size with multiline
	--if actualWidthL's item 1 > maxWidthL's item 1 then error "Left-column string is more than 1 line."
	set {columnL's item 2, theTop, actualWidthL's item 2} to create label ((columnL's item 2) as text) bottom theBottom left inset (maxWidthL's item 1) max width (maxWidthL's item 2) aligns left aligned control size small size with multiline
	{columnL, theTop, (maxWidthL's item 1) + (actualWidthL's item 2)}
end DTcreateSmallFacingLabelValueLabels