Text fields are usually accompanied by some kind of label, so it makes sense to have a handler that can build both at once. So here is a handler that builds a text field with a label above it, simply by calling the the two handlers in the previous post:
-- makes label and field together on makeTopLabeledTextField:enteredText placeholderText:placeholder leftInset:theLeft bottom:theBottom theWidth:theWidth extraHeight:extraHeight label:theLabel set {theField, theTop} to my makeTextField:enteredText placeholderText:placeholder leftInset:theLeft bottom:theBottom theWidth:theWidth extraHeight:extraHeight set {theLabel, theTop, newWidth} to my makeLabel:theLabel leftInset:theLeft bottom:(theTop + 8) maxWidth:theWidth alignment:"left" multiLine:false return {theField, theLabel, theTop} end makeTopLabeledTextField:placeholderText:leftInset:bottom:theWidth:extraHeight:label:
You will see that it limits the label to a single line in this case, which is mostly what is required.
But sometimes you might want the label to appear to the left of the field. This is particularly the case where you have many fields that take shorter values. So here is a separate handler for that case. As well as setting the x-coordinate for the label (leftInset), you also set a value for the left of the field. If this latter value is 0, or less than the leftInset, the field will start directly where the label ends (plus a bit of space). If it's a larger value, the field will aligned to this position, and the label will be placed to its immediate left. This allows you, for example, to have several fields that all line up together.
Here is the code:
on makeSideLabeledTextField:enteredText placeholderText:placeholder leftInset:theLeft bottom:theBottom totalWidth:theWidth label:theLabel fieldLeft:fieldLeft if fieldLeft ≤ theLeft then set {theLabel, theTop, newWidth} to my makeLabel:theLabel leftInset:theLeft bottom:(theBottom + 4) maxWidth:theWidth alignment:"left" multiLine:false set fieldLeft to (newWidth + 8) set {theField, theTop} to my makeTextField:enteredText placeholderText:placeholder leftInset:fieldLeft bottom:theBottom theWidth:(theWidth - newWidth - 8) extraHeight:0 else set {theLabel, theTop, newWidth} to my makeLabel:theLabel leftInset:theLeft bottom:(theBottom + 4) maxWidth:(fieldLeft - theLeft - 8) alignment:"right" multiLine:false set {theField, theTop} to my makeTextField:enteredText placeholderText:placeholder leftInset:fieldLeft bottom:theBottom theWidth:(theWidth - fieldLeft) extraHeight:0 end if -- return theField, theLabel, the top of the field, and left of the field return {theField, theLabel, theTop, fieldLeft} end makeSideLabeledTextField:placeholderText:leftInset:bottom:totalWidth:label:fieldLeft:
Next is a control that does nothing: a horizontal rule. This is just a specialized typ of box, or NSBox. The code makes the box with the given dimensions, then sets it to be a separator with no border and no title. Again, it return its top, as well as the rule:
on makeRuleAt:theBottom leftInset:theLeft theWidth:theWidth set theRule to current application's NSBox's alloc()'s initWithFrame:(current application's NSMakeRect(theLeft, theBottom, theWidth, 1)) tell theRule its setBoxType:(current application's NSBoxSeparator) its setTitlePosition:(current application's NSNoTitle) its setBorderType:(current application's NSLineBorder) end tell return {theRule, theBottom + 1} end makeRuleAt:leftInset:theWidth:
|