diff --git a/Project/Sources/Classes/_DEMO_constraints_Controller.4dm b/Project/Sources/Classes/_DEMO_constraints_Controller.4dm new file mode 100644 index 0000000..992ee43 --- /dev/null +++ b/Project/Sources/Classes/_DEMO_constraints_Controller.4dm @@ -0,0 +1,219 @@ +property form : cs:C1710.formDelegate + +Class constructor + + This:C1470.isSubform:=False:C215 + This:C1470.toBeInitialized:=False:C215 + + // MARK:-Delegates 📦 + This:C1470.form:=cs:C1710.formDelegate.new(This:C1470) + + // Mark: Create and install a minimal menu bar + cs:C1710.menuBar.new().defaultMinimalMenuBar().set() + + This:C1470.form.init() + + // MARK:-[Standard Suite] + // === === === === === === === === === === === === === === === === === === === === === +Function init() + + // Mark: Instantiate the widgets we want to manipulate. + This:C1470.helloWorld:=This:C1470.form.static.new("helloWorld") + This:C1470.helloWidth:=This:C1470.form.input.new("coord") + + This:C1470.bonjourLeMonde:=This:C1470.form.static.new("bonjourLeMonde") + + This:C1470.listbox:=This:C1470.form.listbox.new("List Box") + This:C1470.header1:=This:C1470.form.static.new("label") + This:C1470.header2:=This:C1470.form.static.new("label1") + + // Mark: Define the constraints + // The vertical center line must always be centered + This:C1470.form.constraints.add({\ + target: "middleLine"; \ + type: "horizontal-alignment"; \ + alignment: "center"\ + }) + + // The left panel should always be 50% of the window width + This:C1470.form.constraints.add({\ + target: "left"; \ + type: "right"; \ + value: 50\ + }) + + // The right edge of the first hello world must be in the middle (50%), + // & the width must be no less than 130px and no more than 520 px + This:C1470.form.constraints.add({target: This:C1470.helloWorld; set: [\ + {type: "right"; value: 50}; \ + {type: "minimum-width"; value: 130}; \ + {type: "maximum-width"; value: 520}\ + ]}) + + // The width indicator must stay on right separated by 10px + This:C1470.form.constraints.add({\ + target: This:C1470.helloWidth; \ + type: "margin"; \ + alignment: "left"; \ + margin: 10; \ + reference: This:C1470.helloWorld\ + }) + + // Show red bullet if maximum width is reached + This:C1470.form.constraints.add({formula: Formula:C1597(OBJECT SET VISIBLE:C603(*; "redBullet"; cs:C1710.coord.new("helloWorld").width=520))}) + + // Associated comments ("Text5" & "Text7") are anchored to the left of the width indicator + This:C1470.form.constraints.add({\ + target: "Text5,Text7"; \ + type: "anchor"; \ + alignment: "left"; \ + reference: This:C1470.helloWidth\ + }) + + // This label must use the full width of the left panel, with a 20px margin to the left and right. + This:C1470.form.constraints.add({\ + target: This:C1470.bonjourLeMonde; \ + type: "fit-width"; \ + reference: "left"; \ + margin: 20\ + }) + + // The right edge of the lisbox must be in the middle (50%), + // & the width must be no less than 130px and no more than 520 px + This:C1470.form.constraints.add({target: This:C1470.listbox; set: [\ + {type: "right"; value: 50}; \ + {type: "minimum-width"; value: 150}; \ + {type: "maximum-width"; value: 520}\ + ]}) + + // The header of column 1 is anchored to the right of the column with a -10px offset + This:C1470.form.constraints.add({\ + target: This:C1470.header1; \ + type: "anchor"; \ + alignment: "right"; \ + reference: This:C1470.listbox.getColumnName(1); \ + margin: 10\ + }) + + // Associated comment is anchored to the right of the header label + This:C1470.form.constraints.add({\ + target: "Text9"; \ + type: "anchor"; \ + alignment: "right"; \ + reference: This:C1470.header1\ + }) + + // The header of column 2 is anchored to the left of the column with a +10px offset + This:C1470.form.constraints.add({\ + target: This:C1470.header2; \ + type: "anchor"; \ + alignment: "left"; \ + reference: This:C1470.listbox.getColumnName(2); \ + margin: 10\ + }) + + // Associated comment is anchored to the left of the header label + This:C1470.form.constraints.add({\ + target: "Text10"; \ + type: "anchor"; \ + alignment: "left"; \ + reference: This:C1470.header2\ + }) + + // The colored rectangle is centered on column 2 + This:C1470.form.constraints.add({\ + target: "rectangle"; \ + type: "horizontal-alignment"; \ + alignment: "center"; \ + reference: This:C1470.listbox.getColumnName(1)\ + }) + + // Associated comment is anchored to the center of the rectangle + This:C1470.form.constraints.add({\ + target: "Text8"; \ + type: "anchor"; \ + alignment: "center"; \ + reference: "rectangle"\ + }) + + + // === === === === === === === === === === === === === === === === === === === === === +Function handleEvents($e : cs:C1710.evt) + + $e:=$e || cs:C1710.evt.new() + + If ($e.form) + + // Mark: FORM METHOD + + Case of + + //============================================== + : ($e.load) + + This:C1470.form.onLoad() + + //============================================== + : ($e.resize) + + // Applying the constraints + This:C1470.form.constraints.apply() + + //============================================== + End case + + Else + + // Mark: WIDGETS METHOD + + End if + + // === === === === === === === === === === === === === === === === === === === === === +Function onLoad() + + /// Mark: Set window title + This:C1470.form.window.title:="Constraints" + + // These elements must be distributed according to their content + // They should only be applied once (if the content is not modified), + // which is why the "toDelete" property is set to True + This:C1470.form.static.new("lang").bestSize() + This:C1470.form.static.new("bonjour").bestSize() + + This:C1470.form.constraints.add({\ + target: "bonjour"; \ + type: "inline"; \ + reference: "lang"; \ + toDelete: True:C214\ + }) + + This:C1470.form.constraints.add({\ + target: "monde"; \ + type: "inline"; \ + reference: "bonjour"; \ + toDelete: True:C214\ + }) + + This:C1470.form.static.new("lang1").bestSize() + This:C1470.form.static.new("bonjour1").bestSize() + + This:C1470.form.constraints.add({\ + target: "bonjour1"; \ + type: "inline"; \ + reference: "lang1"; \ + toDelete: True:C214\ + }) + + This:C1470.form.constraints.add({\ + target: "monde1"; \ + type: "inline"; \ + reference: "bonjour1"; \ + toDelete: True:C214\ + }) + + // Applying the constraints + This:C1470.form.constraints.apply() + + // Rules marked as toDelete have been deleted + + \ No newline at end of file diff --git a/Project/Sources/Classes/constraintsDelegate.4dm b/Project/Sources/Classes/constraintsDelegate.4dm new file mode 100644 index 0000000..22be30d --- /dev/null +++ b/Project/Sources/Classes/constraintsDelegate.4dm @@ -0,0 +1,456 @@ +property rules : Collection + +Class constructor($metrics : Object) + + This:C1470.rules:=[] + + This:C1470.scrollBarWidth:=$metrics.scrollBarWidth || Is macOS:C1572 ? 15 : 15 + This:C1470.marginV:=$metrics.marginV || Is macOS:C1572 ? 2 : 2 + This:C1470.marginH:=$metrics.marginH || Is macOS:C1572 ? 20 : 20 + + This:C1470.offset:=2 + + This:C1470._matrix:=Not:C34(Is compiled mode:C492) // True if Dev mode + + // === === === === === === === === === === === === === === === === === === === === === === === === +Function add($rule : Object) : cs:C1710.constraintsDelegate + + var $name : Text + var $o : Object + + If ($rule.set#Null:C1517) + + If (Value type:C1509($rule.target)=Is object:K8:27)\ + && ($rule.target.name#Null:C1517) + + $name:=$rule.target.name + + Else + + $name:=String:C10($rule.target) + + End if + + For each ($o; $rule.set) + + $o.target:=$name + + If ($o.reference#Null:C1517)\ + && (Value type:C1509($o.reference)=Is object:K8:27)\ + && ($o.reference.name#Null:C1517) + + + $o.reference:=$o.reference.name + + End if + + This:C1470.rules.push($o) + + End for each + + Else + + If (Value type:C1509($rule.target)=Is object:K8:27)\ + && ($rule.target.name#Null:C1517) + + $rule.target:=$rule.target.name + + End if + + If ($rule.reference#Null:C1517)\ + && (Value type:C1509($rule.reference)=Is object:K8:27)\ + && ($rule.reference.name#Null:C1517) + + $rule.reference:=$rule.reference.name + + End if + + + This:C1470.rules.push($rule) + + End if + + return This:C1470 + + // === === === === === === === === === === === === === === === === === === === === === === === === + // Dealing with constraints +Function apply() + + var $offset : Real + var $alignment; $name : Text + var $horizontal; $vertical : Boolean + var $height; $max; $type; $width : Integer + var $rule : Object + var $targets : Collection + var $cur; $ref; $viewport : cs:C1710.coord + + // Get the viewport + OBJECT GET SUBFORM CONTAINER SIZE:C1148($width; $height) + $viewport:=cs:C1710.coord.new(0; 0; $width; $height) + + For each ($rule; This:C1470.rules) + + If ($rule.formula#Null:C1517)\ + && (OB Instance of:C1731($rule.formula; 4D:C1709.Function)) + + $rule.formula.call(Null:C1517) + continue + + End if + + Case of + + //______________________________________________________ + : (Value type:C1509($rule.target)=Is collection:K8:32) + + $targets:=$rule.target + + //______________________________________________________ + : (Value type:C1509($rule.target)=Is text:K8:3) + + // Can be a comma-separated list of object names + $targets:=Split string:C1554($rule.target; ","; sk ignore empty strings:K86:1+sk trim spaces:K86:2) + + //______________________________________________________ + Else + + ASSERT:C1129(This:C1470._matrix; "rule.target should be a Text or a collection") + continue + + //______________________________________________________ + End case + + If ($targets.length=0) + + continue + + End if + + For each ($name; $targets) + + $type:=OBJECT Get type:C1300(*; $name) + + If ($type=Object type unknown:K79:1) + + ASSERT:C1129(This:C1470._matrix; "Unknown object name:"+$name) + continue + + End if + + // Current object + $cur:=cs:C1710.coord.new($name) + + // Reference object + If ($rule.reference#Null:C1517) + + $ref:=cs:C1710.coord.new($rule.reference) + + Else + + // The reference is the viewport + $ref:=$viewport + + // FIXME:For a sub-form, determine whether there is a vertical scroll bar. + // This is a property of the container… + //$ref.right-=This.scrollBarWidth + + End if + + Case of + + //______________________________________________________ + // Defines the right edge of an element as a percentage of the reference or the form width + : ($rule.type="right") // Set the right edge in percent of the reference + + // MARK:right + $width:=$ref.width*($rule.value<1 ? $rule.value : $rule.value/100) + $width-=$cur.left + $cur.right:=$cur.left+$width + + Case of + + //…………………………………………………………………………………………………………… + : ($type=Object type text input:K79:4) + + // The scrollbar is outside + OBJECT GET SCROLLBAR:C1076(*; $name; $horizontal; $vertical) + + If ($vertical) + + $cur.right-=This:C1470.scrollBarWidth + + End if + + //…………………………………………………………………………………………………………… + : ($type=Object type picture input:K79:5) + + $cur.right+=This:C1470.offset + + //…………………………………………………………………………………………………………… + : ($type=Object type rectangle:K79:32) + + $cur.right+=(This:C1470.offset*2) + + //…………………………………………………………………………………………………………… + : ($type=Object type popup dropdown list:K79:13) + + $cur.right+=5 + + //…………………………………………………………………………………………………………… + End case + + $cur.apply() + + //______________________________________________________ + : ($rule.type="minimum-width") // Minimum object width + + // MARK:minimum-width + $width:=Num:C11($rule.value) + + Case of + + //…………………………………………………………………………………………………………… + : ($type=Object type popup dropdown list:K79:13) + + $width+=4 + + //…………………………………………………………………………………………………………… + End case + + If ($cur.width<$width) + + $cur.right:=$cur.left+$width + $cur.apply() + + End if + + //______________________________________________________ + : ($rule.type="maximum-width") // Maximum object width + + // MARK:maximum-width + $width:=Num:C11($rule.value) + + Case of + + //…………………………………………………………………………………………………………… + : ($type=Object type popup dropdown list:K79:13) + + $width+=4 + + //…………………………………………………………………………………………………………… + End case + + If ($cur.width>$width) + + $cur.right:=$cur.left+$width + $cur.apply() + + End if + + //______________________________________________________ + : ($rule.type="fit-width") // Adjust width to reference width minus offset if any + + // MARK:fit-width + $cur.right:=$cur.left+($ref.right-$cur.left)-($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.marginH) + $cur.apply() + + //______________________________________________________ + : ($rule.type="margin") // Horizontal offset + + // MARK:margin + $alignment:=String:C10($rule.alignment) + + Case of + + //…………………………………………………………………………………………… + : ($alignment="auto") // Center objects vertically + + $offset:=($ref.width-$cur.width)/2 + + If ($offset>0) + + $width:=$cur.width + $cur.left:=$ref.left+$offset + $cur.right:=$cur.left+$width + + End if + + //…………………………………………………………………………………………… + : ($alignment="left") // Horizontal offset from left side of reference + + $width:=$cur.width + $cur.left:=$ref.right+($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.marginH) + $cur.right:=$cur.left+$width + + //…………………………………………………………………………………………… + : ($alignment="right") // Horizontal offset from right side of reference + + $cur.right:=$ref.left-($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.marginH) + + //…………………………………………………………………………………………… + End case + + $cur.apply() + + //______________________________________________________ + : ($rule.type="horizontal-alignment") + + // MARK:horizontal-alignment + $alignment:=String:C10($rule.alignment) + + Case of + + //…………………………………………………………………………………………… + : ($alignment="center") // Center objects vertically + + $offset:=(($ref.width/2)+$ref.left)-(($cur.width/2)+$cur.left) + $cur.left+=$offset + $cur.right+=$offset + + //…………………………………………………………………………………………… + : ($alignment="left") // Keep objects aligned on the left + + $width:=$cur.width + $cur.left:=$ref.left+($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.marginH) + $cur.right:=$cur.left+$width + + //…………………………………………………………………………………………… + : ($alignment="right") // Keep objects aligned on the right + + $width:=$cur.width + $cur.right:=$ref.right-($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.marginH) + $cur.left:=$cur.right-$width + + //…………………………………………………………………………………………… + End case + + $cur.apply() + + //______________________________________________________ + : ($rule.type="vertical-alignment") + + // TODO:Vertical alignment + + //______________________________________________________ + : ($rule.type="anchor") + + // MARK:anchor + $alignment:=String:C10($rule.alignment) + + Case of + + //…………………………………………………………………………………………… + : ($alignment="center") // Center objects vertically + + $offset:=(($ref.width/2)+$ref.left)-(($cur.width/2)+$cur.left) + $cur.left+=$offset + $cur.right+=$offset + + //…………………………………………………………………………………………… + : ($alignment="left") // Keep objects aligned on the left + + $width:=$cur.width + $cur.left:=$ref.left+Num:C11($rule.margin) + $cur.right:=$cur.left+$width + + //…………………………………………………………………………………………… + : ($alignment="right") // Keep objects aligned on the right + + $width:=$cur.width + $cur.right:=$ref.right-Num:C11($rule.margin) + $cur.left:=$cur.right-$width + + //…………………………………………………………………………………………… + End case + + $cur.apply() + + //______________________________________________________ + : ($rule.type="inline") + + // MARK:inline + If ($rule.reference=Null:C1517) + + ASSERT:C1129(This:C1470._matrix; "Do not omit reference!") + continue + + End if + + $width:=$cur.width + $cur.left:=$ref.left+$ref.width+($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.offset) + $cur.right:=$cur.left+$width + $cur.apply() + + //______________________________________________________ + : ($rule.type="tile") // Set width as percent of the reference + + // MARK:tile + // Calculate proportional width + $width:=Int:C8(($ref.width)*Num:C11($rule.value)) + + If ($rule.parent#Null:C1517) + + // Left is the parent right + $ref:=cs:C1710.coord.new($rule.parent) + $cur.left:=$ref.right+Num:C11(OBJECT Get type:C1300(*; $name+".border")#Object type unknown:K79:1) + + End if + + $cur.right:=$cur.left+$width + $cur.apply() + + //______________________________________________________ + : ($rule.type="float") + + // MARK:float + $alignment:=String:C10($rule.value) + + Case of + + //…………………………………………………………………………………………… + : ($alignment="left") + + $width:=$cur.width + + $cur.right:=$ref.left-($rule.margin#Null:C1517 ? Num:C11($rule.margin) : This:C1470.marginH) + $max:=Num:C11($rule.maximum) + + If ($max#0) + + $cur.right:=$cur.right>$max ? $max : $cur.right + + End if + + $cur.left:=$cur.right-$width + + //…………………………………………………………………………………………… + Else + + ASSERT:C1129(This:C1470._matrix; "Unmanaged alignment:"+$alignment) + continue + + //…………………………………………………………………………………………… + End case + + $cur.apply() + + //______________________________________________________ + Else + + ASSERT:C1129(This:C1470._matrix; "Unknown constraint:"+String:C10($rule.type)) + continue + + //______________________________________________________ + End case + + // Adjust the border if any + If (OBJECT Get type:C1300(*; $name+".border")=Object type unknown:K79:1) + + continue + + End if + End for each + End for each + + // Delete one-shot rules + This:C1470.rules:=This:C1470.rules.filter(Formula:C1597($1.result:=Bool:C1537($1.value.toDelete)=False:C215)) \ No newline at end of file diff --git a/Project/Sources/Classes/coord.4dm b/Project/Sources/Classes/coord.4dm index 28077fd..573a166 100644 --- a/Project/Sources/Classes/coord.4dm +++ b/Project/Sources/Classes/coord.4dm @@ -1,15 +1,39 @@ -Class constructor($left : Integer; $top : Integer; $right : Integer; $bottom : Integer) +Class constructor($left; $top : Integer; $right : Integer; $bottom : Integer) + + Case of + + //______________________________________________________ + : (Value type:C1509($left)=Is object:K8:27)\ + && ($left.coordinates#Null:C1517) // Widget + + This:C1470.name:=$left.name + + var $o : Object + $o:=$left.getCoordinates() + + $left:=$o.left + $top:=$o.top + $right:=$o.right + $bottom:=$o.bottom + + //______________________________________________________ + : (Value type:C1509($left)=Is text:K8:3) // Object name + + This:C1470.name:=$left + OBJECT GET COORDINATES:C663(*; This:C1470.name; $left; $top; $right; $bottom) + + //______________________________________________________ + End case This:C1470.left:=$left This:C1470.top:=$top This:C1470.right:=$right This:C1470.bottom:=$bottom - // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== + // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== Function get windowCoordinates() : Object var $bottom; $left; $right; $top : Integer - var $o : Object $left:=This:C1470.left $top:=This:C1470.top @@ -19,14 +43,17 @@ Function get windowCoordinates() : Object CONVERT COORDINATES:C1365($left; $top; XY Current form:K27:5; XY Current window:K27:6) CONVERT COORDINATES:C1365($right; $bottom; XY Current form:K27:5; XY Current window:K27:6) - $o:={left: $left; top: $top; right: $right; bottom: $bottom} - return $o + return {\ + left: $left; \ + top: $top; \ + right: $right; \ + bottom: $bottom\ + } - // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== + // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== Function get screenCoordinates() : Object var $bottom; $left; $right; $top : Integer - var $o : Object $left:=This:C1470.left $top:=This:C1470.top @@ -36,34 +63,38 @@ Function get screenCoordinates() : Object CONVERT COORDINATES:C1365($left; $top; XY Current form:K27:5; XY Screen:K27:7) CONVERT COORDINATES:C1365($right; $bottom; XY Current form:K27:5; XY Screen:K27:7) - $o:={left: $left; top: $top; right: $right; bottom: $bottom} - return $o + return {\ + left: $left; \ + top: $top; \ + right: $right; \ + bottom: $bottom\ + } - // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== + // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== Function get width() : Integer return This:C1470.right-This:C1470.left - // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== + // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== Function get height() : Integer return This:C1470.bottom-This:C1470.top - // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== + // <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== <== Function get dimensions() : Object - var $o : Object - - $o:={width: This:C1470.width; height: This:C1470.height} - return $o + return {\ + width: This:C1470.width; \ + height: This:C1470.height\ + } // === === === === === === === === === === === === === === === === === === === === === === === === -Function applyToWindow($winRef : Integer) +Function apply($name : Text) - SET WINDOW RECT:C444(This:C1470.left; This:C1470.top; This:C1470.right; This:C1470.bottom; $winRef) + $name:=$name || This:C1470.name + OBJECT SET COORDINATES:C1248(*; $name; This:C1470.left; This:C1470.top; This:C1470.right; This:C1470.bottom) // === === === === === === === === === === === === === === === === === === === === === === === === -Function applyToWidget($name : Text) +Function applyToWindow($winRef : Integer) - OBJECT SET COORDINATES:C1248(*; $name; This:C1470.left; This:C1470.top; This:C1470.right; This:C1470.bottom) - \ No newline at end of file + SET WINDOW RECT:C444(This:C1470.left; This:C1470.top; This:C1470.right; This:C1470.bottom; $winRef) \ No newline at end of file diff --git a/Project/Sources/Classes/formDelegate.4dm b/Project/Sources/Classes/formDelegate.4dm index 548a96a..3c22ff1 100644 --- a/Project/Sources/Classes/formDelegate.4dm +++ b/Project/Sources/Classes/formDelegate.4dm @@ -114,6 +114,9 @@ Class constructor($param) This:C1470.window:=cs:C1710.windowDelegate.new(This:C1470) This:C1470.__DELEGATES__.push(This:C1470.window) + This:C1470.constraints:=cs:C1710.constraintsDelegate.new() + This:C1470.__DELEGATES__.push(This:C1470.constraints) + This:C1470._instantiableWidgets:=[\ This:C1470.static; \ This:C1470.button; \ diff --git a/Project/Sources/Classes/listboxDelegate.4dm b/Project/Sources/Classes/listboxDelegate.4dm index d57df31..eb1a3d1 100644 --- a/Project/Sources/Classes/listboxDelegate.4dm +++ b/Project/Sources/Classes/listboxDelegate.4dm @@ -379,22 +379,37 @@ Function columnNumber($name : Text) : Integer return $indx // === === === === === === === === === === === === === === === === === === === === === === === === === === -Function columnName($number : Integer) : Text +Function getColumnName($columnNumber : Integer) : Text - ARRAY BOOLEAN:C223($isVisible; 0) - ARRAY POINTER:C280($columnsPtr; 0) - ARRAY POINTER:C280($footersPtr; 0) - ARRAY POINTER:C280($headersPtr; 0) - ARRAY POINTER:C280($stylesPtr; 0) - ARRAY TEXT:C222($columns; 0) + If (This:C1470.definition=Null:C1517) + + This:C1470.updateDefinition() + + End if - LISTBOX GET ARRAYS:C832(*; This:C1470.name; \ - $columns; $headers; \ - $columnsPtr; $headersPtr; \ - $isVisible; \ - $stylesPtr) + return String:C10(This:C1470.definition[$columnNumber-1].name) - return $columns{$number} + // === === === === === === === === === === === === === === === === === === === === === === === === === === +Function getHeaderName($columnNumber : Integer) : Text + + If (This:C1470.definition=Null:C1517) + + This:C1470.updateDefinition() + + End if + + return String:C10(This:C1470.definition[$columnNumber-1].header) + + // === === === === === === === === === === === === === === === === === === === === === === === === === === +Function getFooterName($columnNumber : Integer) : Text + + If (This:C1470.definition=Null:C1517) + + This:C1470.updateDefinition() + + End if + + return String:C10(This:C1470.definition[$columnNumber-1].footer) // MARK:- [⚠️ ARRAY TYPE LIST BOXES] // === === === === === === === === === === === === === === === === === === === === === === === === === === @@ -404,7 +419,7 @@ Function setRowForegroundColor($row : Integer; $color; $target) If (This:C1470.isArray(Current method name:C684)) $target:=Count parameters:C259>=3\ - ? Value type:C1509($target)=Is text:K8:3 ? $target : This:C1470.columnName(Num:C11($target))\ + ? Value type:C1509($target)=Is text:K8:3 ? $target : This:C1470.getColumnName(Num:C11($target))\ : This:C1470.name LISTBOX SET ROW COLOR:C1270(*; $target; $row; $color) @@ -420,7 +435,7 @@ Function resetForegroundColor($target) If (This:C1470.isArray(Current method name:C684)) $target:=Count parameters:C259>=1\ - ? Value type:C1509($target)=Is text:K8:3 ? $target : This:C1470.columnName(Num:C11($target))\ + ? Value type:C1509($target)=Is text:K8:3 ? $target : This:C1470.getColumnName(Num:C11($target))\ : This:C1470.name For ($row; 1; This:C1470.rowsNumber; 1) @@ -476,9 +491,10 @@ Function cellPosition($e : cs:C1710.evt) : Object End if - return New object:C1471(\ - "column"; $column; \ - "row"; $row) + return {\ + column: $column; \ + row: $row\ + } // === === === === === === === === === === === === === === === === === === === === === === === === === === // ⚠️ @@ -514,11 +530,12 @@ Function rowCoordinates($row : Integer) : Object $bottom:=($bottom>This:C1470.coordinates.bottom) ? This:C1470.coordinates.bottom : $bottom - return New object:C1471(\ - "left"; $left; \ - "top"; $top; \ - "right"; $right; \ - "bottom"; $bottom) + return {\ + left: $left; \ + top: $top; \ + right: $right; \ + bottom: $bottom\ + } // === === === === === === === === === === === === === === === === === === === === === === === === === === Function cellCoordinates($column : Integer; $row : Integer) : Object @@ -547,7 +564,7 @@ Function cellCoordinates($column : Integer; $row : Integer) : Object LISTBOX GET CELL COORDINATES:C1330(*; This:C1470.name; $column; $row; $left; $top; $right; $bottom) - This:C1470.cellBox:=This:C1470.cellBox || New object:C1471 + This:C1470.cellBox:=This:C1470.cellBox || {} This:C1470.cellBox.left:=$left This:C1470.cellBox.top:=$top @@ -602,7 +619,7 @@ Function select($row : Integer) : cs:C1710.listboxDelegate This:C1470.item:=This:C1470.getValue()[$row-1] This:C1470.itemPosition:=$row-1 - This:C1470.items:=New collection:C1472(This:C1470.item) + This:C1470.items:=[This:C1470.item] Else @@ -807,25 +824,26 @@ Function updateDefinition() : cs:C1710.listboxDelegate $stylesPtr; \ $footers; $footersPtr) - This:C1470.definition:=New collection:C1472 + This:C1470.definition:=[] ARRAY TO COLLECTION:C1563(This:C1470.definition; \ $columns; "name"; \ $headers; "header"; \ $footers; "footer") - This:C1470.columns:=New object:C1471 + This:C1470.columns:={} $o:=This:C1470._columnProperties() For ($i; 1; Size of array:C274($columns); 1) - This:C1470.columns[$columns{$i}]:=New object:C1471(\ - "number"; $i; \ - "visible"; $isVisible{$i}; \ - "enterable"; OBJECT Get enterable:C1067(*; $columns{$i}); \ - "height"; LISTBOX Get row height:C1408(*; This:C1470.name; $i); \ - "pointer"; $columnsPtr{$i}) + This:C1470.columns[$columns{$i}]:={\ + number: $i; \ + visible: $isVisible{$i}; \ + enterable: OBJECT Get enterable:C1067(*; $columns{$i}); \ + height: LISTBOX Get row height:C1408(*; This:C1470.name; $i); \ + pointer: $columnsPtr{$i}\ + } For each ($key; $o) @@ -958,7 +976,7 @@ Function getProperties($column : Text) : Object End if - $properties:=New object:C1471 + $properties:={} For each ($key; $o) @@ -1067,7 +1085,7 @@ Function saveProperties() var $unit : Integer var $o; $properties : Object - $properties:=New object:C1471 + $properties:={} $o:=This:C1470._listboxProperties() @@ -1144,29 +1162,29 @@ Function _listboxProperties() : Object $o:=This:C1470._commonProperties() - $o.detailFormName:=New object:C1471("k"; lk detail form name:K53:44) - $o.displayFooter:=New object:C1471("k"; lk display footer:K53:20) - $o.displayHeader:=New object:C1471("k"; lk display header:K53:4) - $o.doubleClickOnRow:=New object:C1471("k"; lk double click on row:K53:43) - $o.extraRows:=New object:C1471("k"; lk extra rows:K53:38) - $o.hideSelectionHighlight:=New object:C1471("k"; lk hide selection highlight:K53:41) - $o.highlightSet:=New object:C1471("k"; lk highlight set:K53:66) - $o.horScrollbarHeight:=New object:C1471("k"; lk hor scrollbar height:K53:7) - $o.movableRows:=New object:C1471("k"; lk movable rows:K53:76) - $o.namedSelection:=New object:C1471("k"; lk named selection:K53:67) - $o.resizingMode:=New object:C1471("k"; lk resizing mode:K53:36) - $o.rowHeightUnit:=New object:C1471("k"; lk row height unit:K53:42) - $o.selectionMode:=New object:C1471("k"; lk selection mode:K53:35) - $o.singleClickEdit:=New object:C1471("k"; lk single click edit:K53:70) - $o.sortable:=New object:C1471("k"; lk sortable:K53:45) - $o.verScrollbarWidth:=New object:C1471("k"; lk ver scrollbar width:K53:9) + $o.detailFormName:={k: lk detail form name:K53:44} + $o.displayFooter:={k: lk display footer:K53:20} + $o.displayHeader:={k: lk display header:K53:4} + $o.doubleClickOnRow:={k: lk double click on row:K53:43} + $o.extraRows:={k: lk extra rows:K53:38} + $o.hideSelectionHighlight:={k: lk hide selection highlight:K53:41} + $o.highlightSet:={k: lk highlight set:K53:66} + $o.horScrollbarHeight:={k: lk hor scrollbar height:K53:7} + $o.movableRows:={k: lk movable rows:K53:76} + $o.namedSelection:={k: lk named selection:K53:67} + $o.resizingMode:={k: lk resizing mode:K53:36} + $o.rowHeightUnit:={k: lk row height unit:K53:42} + $o.selectionMode:={k: lk selection mode:K53:35} + $o.singleClickEdit:={k: lk single click edit:K53:70} + $o.sortable:={k: lk sortable:K53:45} + $o.verScrollbarWidth:={k: lk ver scrollbar width:K53:9} Case of //______________________________________________________ : (This:C1470.isCollection() || This:C1470.isEntitySelection()) - $o.metaExpression:=New object:C1471("k"; lk meta expression:K53:75) + $o.metaExpression:={k: lk meta expression:K53:75} //______________________________________________________ End case @@ -1180,29 +1198,25 @@ Function _columnProperties() : Object $o:=This:C1470._commonProperties() - $o.allowWordwrap:=New object:C1471("k"; lk allow wordwrap:K53:39) - $o.columnMaxWidth:=New object:C1471("k"; lk column max width:K53:51) - $o.columnMinWidth:=New object:C1471("k"; lk column min width:K53:50) - $o.columnResizable:=New object:C1471("k"; lk column resizable:K53:40) - $o.displayType:=New object:C1471("k"; lk display type:K53:46) - $o.multiStyle:=New object:C1471("k"; lk multi style:K53:71) + $o.allowWordwrap:={k: lk allow wordwrap:K53:39} + $o.columnMaxWidth:={k: lk column max width:K53:51} + $o.columnMinWidth:={k: lk column min width:K53:50} + $o.columnResizable:={k: lk column resizable:K53:40} + $o.displayType:={k: lk display type:K53:46} + $o.multiStyle:={k: lk multi style:K53:71} return $o // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Function _commonProperties() : Object - var $o : Object - $o:=New object:C1471 - - $o.autoRowHeight:=New object:C1471("k"; lk auto row height:K53:72) - $o.backgroundColorExpression:=New object:C1471("k"; lk background color expression:K53:47) - $o.cellHorizontalPadding:=New object:C1471("k"; lk cell horizontal padding:K53:77) - $o.cellVerticalPadding:=New object:C1471("k"; lk cell vertical padding:K53:78) - $o.fontColorExpression:=New object:C1471("k"; lk font color expression:K53:48) - $o.fontStyleExpression:=New object:C1471("k"; lk font style expression:K53:49) - $o.truncate:=New object:C1471("k"; lk truncate:K53:37) - - return $o - + return {\ + autoRowHeight: {k: lk auto row height:K53:72}; \ + backgroundColorExpression: {k: lk background color expression:K53:47}; \ + cellHorizontalPadding: {k: lk cell horizontal padding:K53:77}; \ + cellVerticalPadding: {k: lk cell vertical padding:K53:78}; \ + fontColorExpression: {k: lk font color expression:K53:48}; \ + fontStyleExpression: {k: lk font style expression:K53:49}; \ + truncate: {k: lk truncate:K53:37}\ + } \ No newline at end of file diff --git a/Project/Sources/Classes/staticDelegate.4dm b/Project/Sources/Classes/staticDelegate.4dm index b6c99de..8310586 100644 --- a/Project/Sources/Classes/staticDelegate.4dm +++ b/Project/Sources/Classes/staticDelegate.4dm @@ -328,7 +328,7 @@ Function bestSize($alignment; $minWidth : Integer; $maxWidth : Integer) : cs:C17 If (Num:C11($o.alignment)=Align left:K42:2) // Add 10 pixels - $width:=$width+10 + //$width:=$width+10 End if diff --git a/Project/Sources/Forms/DEMO_constraints/form.4DForm b/Project/Sources/Forms/DEMO_constraints/form.4DForm new file mode 100644 index 0000000..d0e4e06 --- /dev/null +++ b/Project/Sources/Forms/DEMO_constraints/form.4DForm @@ -0,0 +1,371 @@ +{ + "$4d": { + "version": "1", + "kind": "form" + }, + "windowSizingY": "fixed", + "windowMinHeight": 0, + "windowMaxHeight": 32767, + "events": [ + "onLoad", + "onTimer", + "onResize" + ], + "destination": "detailScreen", + "pages": [ + { + "objects": {} + }, + { + "objects": { + "left": { + "type": "rectangle", + "top": 592, + "left": 0, + "width": 169, + "height": 8, + "fill": "#9400d3", + "stroke": "transparent", + "visibility": "hidden", + "strokeWidth": 1 + }, + "helloWorld": { + "type": "text", + "text": "Hello World", + "top": 99, + "left": 19, + "width": 150, + "height": 16, + "borderStyle": "dotted" + }, + "Text1": { + "type": "text", + "text": "Horizontal Sizing=Grow", + "top": 14, + "left": 19, + "width": 150, + "height": 16, + "borderStyle": "dotted", + "sizingX": "grow", + "stroke": "#ff0000", + "textAlign": "center", + "fontStyle": "italic" + }, + "middleLine": { + "type": "line", + "top": 2, + "left": 169, + "width": 0, + "height": 586, + "stroke": "#1e90ff", + "startPoint": "topLeft" + }, + "middleLine1": { + "type": "line", + "top": 2, + "left": 169, + "width": 0, + "height": 586, + "stroke": "#ff0000", + "startPoint": "topLeft", + "sizingX": "move", + "strokeDashArray": [ + 6, + 2 + ] + }, + "Text2": { + "type": "text", + "text": "right 50%", + "top": 50, + "left": 19, + "width": 150, + "height": 16, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "Text3": { + "type": "text", + "text": "minimum-width 130px", + "top": 65, + "left": 19, + "width": 150, + "height": 16, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "Text4": { + "type": "text", + "text": "maximum-width 520px", + "top": 81, + "left": 19, + "width": 150, + "height": 12, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "coord": { + "type": "input", + "left": 176, + "top": 99, + "width": 50, + "height": 17, + "dataSource": "cs:C1710.coord.new(\"helloWorld\").width", + "dataSourceTypeHint": "number", + "enterable": false, + "focusable": false, + "contextMenu": "none", + "fill": "transparent", + "textAlign": "left", + "borderStyle": "none", + "numberFormat": "###,##0px" + }, + "tips": { + "type": "text", + "text": "Resize horizontally ->", + "top": 566, + "left": 160, + "width": 176, + "height": 16, + "textAlign": "right", + "sizingY": "move", + "sizingX": "move" + }, + "Text6": { + "type": "text", + "text": "fit-width, offset 20px", + "top": 135, + "left": 19, + "width": 150, + "height": 12, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "Text5": { + "type": "text", + "text": "margin-left", + "top": 65, + "left": 176, + "width": 90, + "height": 16, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "Text7": { + "type": "text", + "text": "offset 10px", + "top": 81, + "left": 176, + "width": 90, + "height": 12, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "bonjourLeMonde": { + "type": "text", + "text": "Bonjour le monde", + "top": 153, + "left": 19, + "width": 130, + "height": 16, + "borderStyle": "dotted", + "textAlign": "center" + }, + "List Box": { + "type": "listbox", + "left": 19, + "top": 241, + "width": 150, + "height": 100, + "events": [ + "onClick", + "onHeaderClick", + "onDataChange", + "onSelectionChange" + ], + "showHeaders": false, + "resizingMode": "rightToLeft", + "focusable": false, + "scrollbarHorizontal": "hidden", + "scrollbarVertical": "automatic", + "right": 169, + "columns": [ + { + "header": { + "text": "Header1", + "name": "Header1" + }, + "name": "Column1", + "footer": { + "name": "Footer1" + }, + "maxWidth": 400, + "minWidth": 75, + "width": 85 + }, + { + "header": { + "name": "Header2", + "text": "Header2" + }, + "name": "Column2", + "footer": { + "name": "Footer2" + }, + "maxWidth": 200, + "minWidth": 75, + "width": 85 + } + ] + }, + "label": { + "type": "text", + "text": "1", + "top": 220, + "left": 61, + "width": 18, + "height": 16, + "fontWeight": "bold", + "textAlign": "right" + }, + "label1": { + "type": "text", + "text": "2", + "top": 220, + "left": 99, + "width": 17, + "height": 16, + "fontWeight": "bold" + }, + "Rectangle": { + "type": "rectangle", + "top": 273, + "left": 46, + "width": 31, + "height": 29, + "fill": "#ffff00", + "stroke": "#1e90ff" + }, + "Text8": { + "type": "text", + "text": "anchor-center on rect", + "top": 308, + "left": 21, + "width": 80, + "height": 24, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "textAlign": "center", + "fontSize": 10 + }, + "Text9": { + "type": "text", + "text": "anchor-right with column 1", + "top": 189, + "left": 2, + "width": 77, + "height": 24, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "textAlign": "right", + "fontSize": 10 + }, + "Text10": { + "type": "text", + "text": "anchor-left to column 2", + "top": 189, + "left": 99, + "width": 58, + "height": 24, + "borderStyle": "none", + "fontStyle": "italic", + "stroke": "#0000cd", + "fontSize": 10 + }, + "lang": { + "type": "text", + "text": "French:", + "top": 388, + "left": 19, + "width": 88, + "height": 16 + }, + "bonjour": { + "type": "text", + "text": "Bonjour", + "top": 388, + "left": 115, + "width": 91, + "height": 16, + "stroke": "#1e90ff" + }, + "redBullet": { + "type": "oval", + "top": 81, + "left": 135, + "width": 14, + "height": 13, + "fill": "#ff0000", + "stroke": "transparent" + }, + "monde": { + "type": "text", + "text": "le monde", + "top": 388, + "left": 213, + "width": 91, + "height": 16 + }, + "lang1": { + "type": "text", + "text": "US:", + "top": 368, + "left": 19, + "width": 88, + "height": 16 + }, + "bonjour1": { + "type": "text", + "text": "Hello", + "top": 368, + "left": 115, + "width": 91, + "height": 16, + "stroke": "#1e90ff" + }, + "monde1": { + "type": "text", + "text": "world", + "top": 368, + "left": 213, + "width": 91, + "height": 16 + } + } + } + ], + "geometryStamp": 862, + "editor": { + "activeView": "View 1", + "defaultView": "View 1", + "views": { + "View 1": {} + } + }, + "method": "formMethod", + "formSizeAnchor": "tips" +} \ No newline at end of file diff --git a/Project/Sources/Methods/DEMO_constraints.4dm b/Project/Sources/Methods/DEMO_constraints.4dm new file mode 100644 index 0000000..8bb3073 --- /dev/null +++ b/Project/Sources/Methods/DEMO_constraints.4dm @@ -0,0 +1,15 @@ +//%attributes = {} +var $winRef : Integer + +If (Shift down:C543) + + $winRef:=Open form window:C675("DEMO_constraints"; Plain form window:K39:10; Horizontally centered:K39:1; Vertically centered:K39:4) + +Else + + $winRef:=Open form window:C675("DEMO_constraints"; Plain form window:K39:10; Horizontally centered:K39:1; Vertically centered:K39:4; *) + +End if + +DIALOG:C40("DEMO_constraints") +CLOSE WINDOW:C154($winRef) \ No newline at end of file diff --git a/Project/Sources/folders.json b/Project/Sources/folders.json index a73c9a6..7af4526 100644 --- a/Project/Sources/folders.json +++ b/Project/Sources/folders.json @@ -37,6 +37,7 @@ "buttonDelegate", "colour", "comboBoxDelegate", + "constraintsDelegate", "coord", "dim", "dropDownDelegate", @@ -68,6 +69,14 @@ "_DEMO_1_Controller" ] }, + "DEMO_constraints": { + "forms": [ + "DEMO_constraints" + ], + "classes": [ + "_DEMO_constraints_Controller" + ] + }, "DEMO_menus": { "forms": [ "DEMO_menus" @@ -87,11 +96,13 @@ "DEMOS": { "groups": [ "DEMO_1", + "DEMO_constraints", "DEMO_menus", "DEMO_webArea" ], "methods": [ "DEMO_1", + "DEMO_constraints", "DEMO_menus", "DEMO_webArea" ] diff --git a/brew.json b/brew.json index a921b23..b3661de 100644 --- a/brew.json +++ b/brew.json @@ -10,6 +10,7 @@ "formDelegate.4dm", "buttonDelegate.4dm", "comboBoxDelegate.4dm", + "constraintsDelegate.4dm", "dropDownDelegate.4dm", "groupDelegate.4dm", "hListDelegate.4dm", @@ -48,6 +49,7 @@ "formDelegate.md", "buttonDelegate.md", "comboBoxDelegate.md", + "constraintsDelegate.md", "dropDownDelegate.md", "groupDelegate.md", "hListDelegate.md",