diff --git a/Libraries/iTasks/UI/Definition.dcl b/Libraries/iTasks/UI/Definition.dcl index e57150e36fba6631b064dd65c60efa696111db90..d4f80834d24c047dfd10206907c6bf3ec9f03bbd 100644 --- a/Libraries/iTasks/UI/Definition.dcl +++ b/Libraries/iTasks/UI/Definition.dcl @@ -235,7 +235,7 @@ editorIdAttr :: !String -> UIAttributes taskIdAttr :: !String -> UIAttributes labelAttr :: !String -> UIAttributes styleAttr :: !String -> UIAttributes -classAttr :: !String -> UIAttributes +classAttr :: ![String] -> UIAttributes resizableAttr :: ![UISide] -> UIAttributes maxlengthAttr :: !Int -> UIAttributes minlengthAttr :: !Int -> UIAttributes diff --git a/Libraries/iTasks/UI/Definition.icl b/Libraries/iTasks/UI/Definition.icl index 12c690ca445e470b6c2ad197c882b0ea043f7171..e3d97f34bcdb0a807773675117bba831b9a917c0 100644 --- a/Libraries/iTasks/UI/Definition.icl +++ b/Libraries/iTasks/UI/Definition.icl @@ -195,8 +195,8 @@ labelAttr taskId = 'DM'.fromList [(LABEL_ATTRIBUTE,JSONString taskId)] styleAttr :: !String -> UIAttributes styleAttr style = 'DM'.fromList [("style",JSONString style)] -classAttr :: !String -> UIAttributes -classAttr cls = 'DM'.fromList [("class",JSONString cls)] +classAttr :: ![String] -> UIAttributes +classAttr cls = 'DM'.fromList [("class",JSONArray (map JSONString cls))] resizableAttr :: ![UISide] -> UIAttributes resizableAttr sides = 'DM'.fromList [("resizable",JSONArray (map encodeUI sides))] diff --git a/Libraries/iTasks/UI/Layout/Common.icl b/Libraries/iTasks/UI/Layout/Common.icl index 9e7e281843c03185a8b18b8320f98a777b458d07..30ee15c56937b8e3903bac3210f0bcfcbf576292 100644 --- a/Libraries/iTasks/UI/Layout/Common.icl +++ b/Libraries/iTasks/UI/Layout/Common.icl @@ -17,8 +17,6 @@ import qualified Data.Foldable import qualified Text as T from Text import class Text, instance Text String -LABEL_WIDTH :== 100 - arrangeWithTabs :: Bool -> LayoutRule arrangeWithTabs closeable = layoutSubUIs (SelectAND (SelectByPath []) (SelectByType UIParallel)) @@ -172,7 +170,7 @@ arrangeHorizontal = setUIAttributes (directionAttr Horizontal) frameCompact :: LayoutRule frameCompact = sequenceLayouts - [setUIAttributes ('DM'.unions [frameAttr True,sizeAttr WrapSize WrapSize,marginsAttr 50 0 20 0,minWidthAttr (ExactBound 600)]) + [setUIAttributes ('DM'.unions [classAttr ["itasks-frame-compact"],sizeAttr WrapSize WrapSize]) ,wrapUI UIContainer ,setUIAttributes (halignAttr AlignCenter) ] @@ -320,7 +318,7 @@ toFormItem = layoutSubUIs (SelectAND (SelectByPath []) (SelectOR (SelectByHasAtt (sequenceLayouts //Create the 'row' that holds the form item [wrapUI UIContainer - ,setUIAttributes ('DM'.unions [marginsAttr 2 4 2 4, directionAttr Horizontal,valignAttr AlignMiddle, sizeAttr FlexSize WrapSize]) + ,setUIAttributes ('DM'.unions [classAttr ["itasks-form-item"],directionAttr Horizontal,valignAttr AlignMiddle, sizeAttr FlexSize WrapSize]) //If there is a label attribute, create a label ,optAddLabel //If there is hint attribute, create an extra icon @@ -331,7 +329,7 @@ toFormItem = layoutSubUIs (SelectAND (SelectByPath []) (SelectOR (SelectByHasAtt where optAddLabel = layoutSubUIs (SelectByContains (SelectAND (SelectByPath [0]) (SelectByHasAttribute LABEL_ATTRIBUTE))) addLabel addLabel = sequenceLayouts - [insertChildUI 0 (uia UILabel (widthAttr (ExactSize LABEL_WIDTH))) + [insertChildUI 0 (uia UILabel (widthAttr WrapSize)) ,sequenceLayouts [copySubUIAttributes (SelectKeys ["label","optional","mode"]) [1] [0] ,layoutSubUIs (SelectByPath [0]) (modifyUIAttributes (SelectKeys ["label","optional","mode"]) createLabelText) @@ -354,7 +352,7 @@ where ) addIcon iconIndex = sequenceLayouts - [insertChildUI iconIndex (uia UIIcon (leftMarginAttr 5)) + [insertChildUI iconIndex (ui UIIcon) ,copySubUIAttributes (SelectKeys [HINT_ATTRIBUTE,HINT_TYPE_ATTRIBUTE]) [iconIndex - 1] [iconIndex] ,layoutSubUIs (SelectByPath [iconIndex]) (modifyUIAttributes (SelectKeys [HINT_ATTRIBUTE,HINT_TYPE_ATTRIBUTE]) createIconAttr) ] diff --git a/Libraries/iTasks/UI/Prompt.icl b/Libraries/iTasks/UI/Prompt.icl index be30e8188b25b4899fdf34aed5086ac48f34ea98..16f5640760e5b041483de3c8a38868da7ac5eeff 100644 --- a/Libraries/iTasks/UI/Prompt.icl +++ b/Libraries/iTasks/UI/Prompt.icl @@ -21,7 +21,7 @@ where toPrompt (title,hint) = let (UI type attr items) = createPrompt hint in createPrompt :: String -> UI createPrompt hint = (uiac UIContainer attr [stringDisplay hint]) where - attr = 'DM'.unions [marginsAttr 5 5 10 5, widthAttr FlexSize, minWidthAttr WrapBound, heightAttr WrapSize] + attr = classAttr ["itasks-prompt","itasks-flex-width","itasks-wrap-height"] instance toString Icon where diff --git a/Libraries/iTasks/UI/WebPublic/css/itasks.css b/Libraries/iTasks/UI/WebPublic/css/itasks.css index 46a9947228c8c670e5207e9b86e36b47baa9eb13..783b07f76d64bb48e985c2282d51325aa395bdf2 100644 --- a/Libraries/iTasks/UI/WebPublic/css/itasks.css +++ b/Libraries/iTasks/UI/WebPublic/css/itasks.css @@ -226,6 +226,55 @@ div.itasks-exception { min-width: fit-content; } +/* Transititional classes for alignment */ +.itasks-vcontainer.itasks-halign-left { + align-items: start; +} + +.itasks-vcontainer.itasks-halign-center { + align-items: center; +} + +.itasks-vcontainer.itasks-halign-right { + align-items: end; +} + +.itasks-vcontainer.itasks-valign-top { + justify-content: flex-start; +} + +.itasks-vcontainer.itasks-valign-middle { + justify-content: center; +} + +.itasks-vcontainer.itasks-valign-bottom { + justify-content: flex-end; +} + +.itasks-hcontainer.itasks-halign-left { + justify-content: flex-start; +} + +.itasks-hcontainer.itasks-halign-center { + justify-content: center; +} + +.itasks-hcontainer.itasks-halign-right { + justify-content: flex-end; +} + +.itasks-hcontainer.itasks-valign-top { + align-items: start; +} + +.itasks-hcontainer.itasks-valign-middle { + align-items: center; +} + +.itasks-hcontainer.itasks-valign-bottom { + align-items: end; +} + /* Styles for unlayouted content */ .itasks-raw-record, .itasks-raw-cons, @@ -336,9 +385,24 @@ div.itasks-exception { } .itasks-prompt { - border: #999 solid; - border-width: 0 0 1px 0; min-height: fit-content; + min-width: fit-content; + margin: 5px 5px 10px 5px; +} + +.itasks-form-item { + margin: 2px 4px 2px 4px; +} + +.itasks-form-item .itasks-icon { + margin-left: 5px; +} + +.itasks-frame-compact { + margin: 50px 0 20px 0; + border-radius: 5px; + overflow: hidden; + min-width: 600px; } .itasks-header { @@ -397,6 +461,10 @@ div.itasks-exception { flex-direction: column; } +.itasks-tabset * { + align-self: stretch; +} + .itasks-tabbar { text-align: left; list-style: none; @@ -572,7 +640,7 @@ div.itasks-exception { justify-content: flex-start; align-items: center; margin: 0; - padding: 2px 5px; + padding: 2px; background: #eee; background: linear-gradient(#f8f8f8, #e1e1e1); } @@ -586,6 +654,10 @@ div.itasks-exception { background: linear-gradient(#f8f8f8, #cecece); } +.itasks-buttonbar { + padding: 2px 2px 2px 0; +} + .itasks-list { color: #000; background-color: #fff; @@ -711,6 +783,12 @@ div.itasks-exception { height: 16px; } +.itasks-label { + width: 100px; + padding: 5px; + text-overflow: elipsis; +} + .itasks-button { font-size: 8pt; padding: 3px; @@ -752,6 +830,10 @@ div.itasks-exception { opacity: 0.5; } +.itasks-textview, .itasks-htmlview { + padding: 5px; +} + .itasks-checkgroup { margin: 0; padding: 0; @@ -908,6 +990,10 @@ div.itasks-exception { align-items: stretch; } +.itasks-choice-list * { + align-self: stretch; +} + .itasks-choice-list-option { border: solid #333; border-width: 0 0 1px 0; diff --git a/Libraries/iTasks/UI/WebPublic/css/src/components-container.scss b/Libraries/iTasks/UI/WebPublic/css/src/components-container.scss index 561e7f1bae54c8d5cc3cf12735fc7648f04c8193..d4e72122235e7b0189faa4d9a2458d876764cdba 100644 --- a/Libraries/iTasks/UI/WebPublic/css/src/components-container.scss +++ b/Libraries/iTasks/UI/WebPublic/css/src/components-container.scss @@ -1,9 +1,20 @@ .#{$prefix}prompt { - border: #999 solid; - border-width: 0 0 1px 0; min-height: fit-content; + min-width: fit-content; + margin: 5px 5px 10px 5px; +} +.#{$prefix}form-item { + margin: 2px 4px 2px 4px; +} +.#{$prefix}form-item .#{$prefix}icon { + margin-left: 5px; +} +.#{$prefix}frame-compact { + margin: 50px 0 20px 0; + border-radius: 5px; + overflow: hidden; + min-width: 600px; } - .#{$prefix}header { font-weight: bold; font-size: 11px; @@ -58,6 +69,9 @@ align-items: stretch; flex-direction: column; } +.#{$prefix}tabset * { + align-self: stretch; +} .#{$prefix}tabbar { text-align: left; list-style: none; @@ -217,7 +231,7 @@ justify-content: flex-start; align-items: center; margin: 0; - padding: 2px 5px; + padding: 2px; background: $canvas-base-color; background: linear-gradient(lighten($canvas-base-color,4%), darken($canvas-base-color,5%)); @@ -230,6 +244,9 @@ .#{$prefix}buttonbar, .#{$prefix}toolbar { background: linear-gradient(lighten($button-base-color,4%), darken($button-base-color,12.5%)); } +.#{$prefix}buttonbar { + padding: 2px 2px 2px 0; +} .#{$prefix}list { color: $list-text-color; diff --git a/Libraries/iTasks/UI/WebPublic/css/src/components-core.scss b/Libraries/iTasks/UI/WebPublic/css/src/components-core.scss index 4413ac76a396cfe47510a50243b163d649dc28a1..58d986462d3c2362c6e25c3666fd5ccdea667740 100644 --- a/Libraries/iTasks/UI/WebPublic/css/src/components-core.scss +++ b/Libraries/iTasks/UI/WebPublic/css/src/components-core.scss @@ -72,3 +72,40 @@ div.#{$prefix}exception { min-width: fit-content; } } +/* Transititional classes for alignment */ +.#{$prefix}vcontainer.#{$prefix}halign-left { + align-items: start; +} +.#{$prefix}vcontainer.#{$prefix}halign-center { + align-items: center; +} +.#{$prefix}vcontainer.#{$prefix}halign-right { + align-items: end; +} +.#{$prefix}vcontainer.#{$prefix}valign-top { + justify-content: flex-start; +} +.#{$prefix}vcontainer.#{$prefix}valign-middle { + justify-content: center; +} +.#{$prefix}vcontainer.#{$prefix}valign-bottom { + justify-content: flex-end; +} +.#{$prefix}hcontainer.#{$prefix}halign-left { + justify-content: flex-start; +} +.#{$prefix}hcontainer.#{$prefix}halign-center { + justify-content: center; +} +.#{$prefix}hcontainer.#{$prefix}halign-right { + justify-content: flex-end; +} +.#{$prefix}hcontainer.#{$prefix}valign-top { + align-items: start; +} +.#{$prefix}hcontainer.#{$prefix}valign-middle { + align-items: center; +} +.#{$prefix}hcontainer.#{$prefix}valign-bottom { + align-items: end; +} diff --git a/Libraries/iTasks/UI/WebPublic/css/src/components-display.scss b/Libraries/iTasks/UI/WebPublic/css/src/components-display.scss index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ee60d028c96071f1da586649cc5140b9950e086d 100644 --- a/Libraries/iTasks/UI/WebPublic/css/src/components-display.scss +++ b/Libraries/iTasks/UI/WebPublic/css/src/components-display.scss @@ -0,0 +1,3 @@ +.#{$prefix}textview, .#{$prefix}htmlview { + padding: 5px; +} diff --git a/Libraries/iTasks/UI/WebPublic/css/src/components-form.scss b/Libraries/iTasks/UI/WebPublic/css/src/components-form.scss index 067593f845f6236d10c91f3e7a60cbad3c2b8ceb..c43e96ea28558b99e41a2cb4bc104070d15fec29 100644 --- a/Libraries/iTasks/UI/WebPublic/css/src/components-form.scss +++ b/Libraries/iTasks/UI/WebPublic/css/src/components-form.scss @@ -2,6 +2,11 @@ width: 16px; height: 16px; } +.#{$prefix}label { + width: 100px; + padding: 5px; + text-overflow: elipsis; +} .#{$prefix}button { font-size: 8pt; padding: 3px; diff --git a/Libraries/iTasks/UI/WebPublic/css/src/components-selection.scss b/Libraries/iTasks/UI/WebPublic/css/src/components-selection.scss index f39bccccfbb3cd9db05a57c9e857456f28219940..fa22b43eb519216ece8b520472566673386271de 100644 --- a/Libraries/iTasks/UI/WebPublic/css/src/components-selection.scss +++ b/Libraries/iTasks/UI/WebPublic/css/src/components-selection.scss @@ -150,6 +150,9 @@ flex-direction: column; align-items: stretch; } +.#{$prefix}choice-list * { + align-self: stretch; +} .#{$prefix}choice-list-option { border: solid $select-base-color; border-width: 0 0 1px 0; diff --git a/Libraries/iTasks/UI/WebPublic/js/itasks-components-container.js b/Libraries/iTasks/UI/WebPublic/js/itasks-components-container.js index 081a857f2bf96f96518f8dce2389d5aca54915b1..762675d20402d54c5eb5b96ae174a4c8f8ed0d32 100644 --- a/Libraries/iTasks/UI/WebPublic/js/itasks-components-container.js +++ b/Libraries/iTasks/UI/WebPublic/js/itasks-components-container.js @@ -403,8 +403,7 @@ itasks.ToolBar = { height: 'wrap', width: 'flex', direction: 'horizontal', - halign: 'left', - padding: '2 2 2 2' + halign: 'left' }, }; @@ -414,8 +413,7 @@ itasks.ButtonBar = { height: 'wrap', width: 'flex', direction: 'horizontal', - halign: 'right', - padding: '2 2 2 0' + halign: 'right' } }; itasks.List = { diff --git a/Libraries/iTasks/UI/WebPublic/js/itasks-components-display.js b/Libraries/iTasks/UI/WebPublic/js/itasks-components-display.js index 4effced7259e7dc219f4e10763c743307fa60514..dcc327268194311d5bf6da5b0ae9be94e91919c8 100644 --- a/Libraries/iTasks/UI/WebPublic/js/itasks-components-display.js +++ b/Libraries/iTasks/UI/WebPublic/js/itasks-components-display.js @@ -1,12 +1,7 @@ itasks.TextView = { cssCls: 'textview', container: false, - attributes: { - paddingTop: 5, - paddingRight: 5, - paddingBottom: 5, - paddingLeft: 5 - }, + attributes: {}, initDOMEl: function() { this.domEl.innerHTML = this.attributes.value || ''; }, @@ -21,13 +16,7 @@ itasks.TextView = { }; itasks.HtmlView = { cssCls: 'htmlview', - //Default padding - attributes: { - paddingTop: 5, - paddingRight: 5, - paddingBottom: 5, - paddingLeft: 5 - }, + attributes: {}, initDOMEl: function() { this.domEl.innerHTML = this.attributes.value || ''; }, diff --git a/Libraries/iTasks/UI/WebPublic/js/itasks-components-form.js b/Libraries/iTasks/UI/WebPublic/js/itasks-components-form.js index 805b046739b752b2f307ae2ee6076f82fb9fe60e..e23568f36c7524615a5cd473abf91f569b77c3b8 100644 --- a/Libraries/iTasks/UI/WebPublic/js/itasks-components-form.js +++ b/Libraries/iTasks/UI/WebPublic/js/itasks-components-form.js @@ -404,13 +404,8 @@ itasks.Button = { itasks.Label = { domTag: 'label', container: false, - attributes: { - width: '150px', - paddingTop: 5, - paddingRight: 5, - paddingBottom: 5, - paddingLeft: 5 - }, + cssCls: 'label', + attributes: {}, initDOMEl: function() { var me = this, el = me.domEl; diff --git a/Libraries/iTasks/UI/WebPublic/js/itasks-core.js b/Libraries/iTasks/UI/WebPublic/js/itasks-core.js index 38fb6a9655d4a87bfb2af0a642170411a00bb5d9..7a40315ddcd705b9cca12e043b248f8764d3b612 100644 --- a/Libraries/iTasks/UI/WebPublic/js/itasks-core.js +++ b/Libraries/iTasks/UI/WebPublic/js/itasks-core.js @@ -83,14 +83,16 @@ itasks.Component = { me.domEl.style = me.attributes['style']; } if(me.attributes['class']) { - me.domEl.classList.add(me.attributes['class']); + var len = me.attributes['class'].length; + for(var i = 0; i < len; i++) { + me.domEl.classList.add(me.attributes['class'][i]); + } } //Custom initialization after the dom element has been rendered me.initDOMEl(); //Size the element me.initDOMElSize(); //Set margins and alignment - me.initDOMElMargins(); me.initContainerEl(); //Add the the child renderings @@ -115,8 +117,6 @@ itasks.Component = { el.classList.add(me.cssPrefix + 'wrap-width'); } else { el.style.width = width + 'px'; - el.style.minWidth = width + 'px'; - me.containerEl.style.overflowX = 'auto'; } if(height === 'flex') { el.classList.add(me.cssPrefix + 'flex-height'); @@ -124,99 +124,32 @@ itasks.Component = { el.classList.add(me.cssPrefix + 'wrap-height'); } else { el.style.height = width + 'px'; - el.style.minHeight = width + 'px'; - me.containerEl.style.overflowY = 'auto'; } }, - initDOMElMargins: function() { - var me = this, - el = me.domEl, - width = me.attributes.width, - height = me.attributes.height; - - if(!me.parentCmp) { //Do not set margins on the root component, let the embedding page handle that - return; - } - var parentDirection = (me.parentCmp && me.parentCmp.attributes.direction) || 'vertical', - parentVAlign = (me.parentCmp && me.parentCmp.attributes.valign) || 'top', - parentHAlign = (me.parentCmp && me.parentCmp.attributes.halign) || 'left', - curIdx = me.parentCmp.findChild(me), - lastIdx = me.parentCmp.children.length - 1, - isFirst = (curIdx == 0), - isLast = (curIdx == lastIdx); - - //Set left and right margins as specified - if('marginLeft' in me.attributes) { el.style.marginLeft = me.attributes.marginLeft + 'px'; } - if('marginRight' in me.attributes) { el.style.marginRight = me.attributes.marginRight + 'px' ; } - - //Because vertical borders 'collapse' into each other, we never set the - //bottom-margin, but set top-margin's that also include the bottom margin of - //the previous element - if(parentDirection == 'vertical' && !isFirst) { - //The first element never sets a top-margin. Its top-margin is added to the parent's padding - //and its bottom margin is added to the next elements top-margin - el.style.marginTop = ((me.attributes.marginTop || 0) + (me.parentCmp.children[curIdx - 1].attributes.marginBottom || 0)) + 'px'; - } - - //Set margins to auto based on alignment of parent - if(parentDirection == 'vertical') { - if(width !== 'flex') { - switch(parentHAlign) { - case 'left': el.style.marginRight = 'auto'; break; - case 'center': el.style.marginRight = 'auto'; el.style.marginLeft = 'auto'; break; - case 'right': el.style.marginLeft = 'auto'; break; - } - } - //If this element is the first, maybe also adjust top margin; - if(curIdx === 0 && (parentVAlign == 'middle' || parentVAlign == 'bottom')) { - el.style.marginTop = 'auto'; - } - //If this element is the last, maybe also adjust bottom margin; - if(curIdx === lastIdx && (parentVAlign == 'middle' || 'top')) { - el.style.marginBottom = 'auto'; - } - } else { - if(height !== 'flex') { - switch(parentVAlign) { - case 'top': el.style.marginBottom = 'auto'; break; - case 'middle': el.style.marginBottom = 'auto'; el.style.marginTop = 'auto'; break; - case 'bottom': el.style.marginTop = 'auto'; break; - } - } - //If this element is the first, maybe also adjust left margin; - if(curIdx === 0 && (parentHAlign == 'center' || parentHAlign == 'right')) { - el.style.marginLeft = 'auto'; - } - //If this element is the last, maybe also adjust right margin; - if(curIdx === lastIdx && (parentHAlign == 'center' || parentHAlign == 'left')) { - el.style.marginRight = 'auto'; - } - } - }, initContainerEl: function() { var me = this, el = me.containerEl, horizontal = (me.attributes.direction && (me.attributes.direction === 'horizontal')) || false, - paddingTop, paddingBottom; + valign = me.attributes.valign || 'top', + halign = me.attributes.halign || 'left'; if(me.container === false) { return; } - + //Direction el.classList.add(me.cssPrefix + (horizontal ? 'hcontainer' : 'vcontainer')); - //Set padding - if(me.attributes.paddingRight) { el.style.paddingRight = me.attributes.paddingRight + 'px' ; } - if(me.attributes.paddingLeft) { el.style.paddingLeft = me.attributes.paddingLeft + 'px' ; } - - paddingTop = me.attributes.paddingTop || 0; - paddingBottom = me.attributes.paddingBottom || 0; - if(me.children.length > 0) { - paddingTop += (me.children[0].attributes.marginBottom || 0); - paddingBottom += (me.children[me.children.length - 1].attributes.marginTop || 0); + //Alignment + switch(valign) { + case 'top': el.classList.add(me.cssPrefix + 'valign-top'); break; + case 'middle': el.classList.add(me.cssPrefix + 'valign-middle'); break; + case 'bottom': el.classList.add(me.cssPrefix + 'valign-middle'); break; + } + switch(halign) { + case 'left': el.classList.add(me.cssPrefix + 'halign-left'); break; + case 'center': el.classList.add(me.cssPrefix + 'halign-center'); break; + case 'right': el.classList.add(me.cssPrefix + 'halign-right'); break; } - el.style.paddingTop = paddingTop + 'px'; - el.style.paddingBottom = paddingBottom + 'px'; }, doEditEvent: function (taskId, editorId, value) { var me = this;