@doc hierarchy="GMLDOM">
Layout Code
(c) SAP AG 2003-2006. All rights reserved.
Aspect ControlLayout for Layout; inherit Widget;
override virtual property type = 'control';
virtual property minWidth = 10;
virtual property fixedWidth = 0;
virtual property defaultWidth = 100;
virtual property defaultHeight = 16;
virtual property freeSize = false;
virtual property labelWidth = 0;
virtual property paddingLeft = 0;
virtual property paddingRight = 0;
property formRow = 99999;
property formCol = 99999;
metadata for formCol = { // we need this metadata only for sideEffects
editor: {
visible: false,
sideEffects: true // affects colspan
}
}
override virtual method paint(parentElement)
try {
this.supercall();
var parent = this.getParent();
var group = (parent.type == 'box') ? null : parent.base;
var V = RULE('defineControlWidget', this.board.rtSkin, this.getBox().base, group, base);
var html = '';
if (!V) html = '';
else {
if (V.minWidth !== undefined) {
this.minWidth = V.minWidth;
base.minWidth = V.minWidth;
}
if (V.fixedWidth !== undefined) this.fixedWidth = V.fixedWidth;
if (V.defaultWidth !== undefined) this.defaultWidth = V.defaultWidth;
if (V.defaultHeight !== undefined) this.defaultHeight = V.defaultHeight;
if (V.freeSize !== undefined) this.freeSize = V.freeSize;
this.fixedWidth = V.fixedWidth || 0;
this.labelWidth = V.showLabel ? V.labelWidth : 0;
var pos = this.getBasePos();
var size = this.getBaseSize();
var style = 'left: ' + pos.x + '; top: ' + pos.y + '; width: ' + size.w + '; height: ' + size.h;
html = '';
}
var elem = this.createHtmlElement(html, null, null, this.parentElement);
if (V) {
var H = [];
if (V.showLabel) H.push(this.buildLabelHtml(V, this.id));
if (V.showDecorator || this.hasExternalDecorations()) H.push('' + (V.decoratorHTML || '') + this.buildExtDecoStr() + '');
elem.innerHTML = JOIN(H);
}
this.elem = elem;
if (V && (V.resizePolicy !== undefined)) this.setResizePolicy(V.resizePolicy);
}
catch (e) {
#LOG[2, 'Failed to paint ' + (base.name||base.Class.name)];
}
end
virtual method hasExternalDecorations()
if (this.base.l$externalDecorations && !ISEMPTY(this.base.l$externalDecorations)) return true;
return false;
end
virtual method buildExtDecoStr()
var retArry = [];
for (var k in this.base.l$externalDecorations) retArry.push(this.base.l$externalDecorations[k]);
return JOIN(retArry);
end
override virtual method repaint(attr)
try {
var P = RULE('getWidgetRepaintParts', base, null, attr); if (!P) return;
if (P.pos) this.setPos(this.getBasePos(), true);
if (P.size) {
this.setSize(this.getBaseSize(), true);
if(base.isa('gml2:ImageLoader')) $ENV.fireSyncState({prop:true});
}
if (P.contents || P.label || base.lastElem) this.repaintContents(attr);
}
catch (e) {
#LOG[2, 'Failed to repaint ' + (base.name||base.Class.name)];
}
end
override virtual method repaintContents(attr)
var elem = this.elem;
if (!elem) return;
var parent = this.getParent();
var group = (parent.type == 'box') ? null : parent.base;
var V = RULE('defineControlWidget', this.board.rtSkin, this.getBox().base, group, base);
if (!V) {
elem.style.display = 'none';
return;
}
if (V.resetSize) this.setSize(this.getBaseSize(), true);
if (V.minWidth !== undefined) this.minWidth = V.minWidth;
this.fixedWidth = V.fixedWidth || 0;
if (V.resizePolicy !== undefined) this.setResizePolicy(V.resizePolicy);
if (V.className && (V.className != elem.className)) elem.className = V.className;
if (V.paddingRight && this.paddingRight != V.paddingRight) {
this.paddingRight = V.paddingRight;
elem.style.paddingRight = V.paddingRight;
}
if (V.paddingLeft && this.paddingLeft != V.paddingLeft) {
this.paddingLeft = V.paddingLeft;
elem.style.paddingLeft = V.paddingLeft;
}
elem.title = V.tooltip || '';
elem.disabled = V.disabled || false;
var html = '';
if (V.showLabel) html += this.buildLabelHtml(V, elem.id);
else this.removeLabelHtml(elem.id); // TODO : this action not checked while label after control
if (V.showDecorator || this.hasExternalDecorations()) html += '' + (V.decoratorHTML || '') + this.buildExtDecoStr() + '';
if (!html) {this.board.selection.adjustSelection(); return;}
// NOTE: maltingBox must be without showDecorator!!! (createElement problem)
if (this.isa('#NS[MeltingBoxLayout]')) {
var cNode = elem.childNodes[0]; // Possible label HTML obj
if (cNode) {
if (cNode.part == 'lbl') cNode.outerHTML = html;
else {
var label = this.doc.createElement(html);
label.innerText = V.label;
elem.insertBefore(label, cNode);
// elem.innerHTML = html + elem.innerHTML;
}
} else elem.innerHTML = html;
} else elem.innerHTML = html;
this.labelWidth = V.showLabel ? V.labelWidth : 0;
// Adjusting selection to correct size after changes in selected object's html
this.board.selection.adjustSelection();
end
//override virtual method getLabelText()
// var lbl = this.elem.childNodes[0];
// return lbl && (lbl.part == 'lbl' || lbl.part == 'deco') && lbl.innerHTML || null; // the text can have HTML with tags
//end
//override virtual method getLabelWidth()
// var lbl = this.elem.childNodes[0];
// return lbl && (lbl.part == 'lbl') && lbl.offsetWidth || 0;
//end
<@doc scope="private">
Build the control HTML label.
The values object for creating the label
The elem ID creating a unique id
virtual method buildLabelHtml(values, uID)
var label = values.label;
var labelWidth = values.labelWidth;
var left = (typeof labelWidth == 'number') ? -(labelWidth + 1) : 0;
var labelClass = values.labelClass || '';
if (values.showNotch) labelClass + ' LBL-NOTCH';
var style1 = 'left: ' + left + '; width: ' + labelWidth;
var star = '';
if (values.showMandatory) {
var width = labelWidth < values.actualLabelWidth + values.mandatoryWidth ?
labelWidth - values.mandatoryWidth : values.actualLabelWidth;
style1 = 'left: ' + left + '; width: ' + width;
var style2 = 'left: ' + (left + width + 1) + '; width: ' + values.mandatoryWidth;
star = '*'
}
return '' + label + '' + star;
end
virtual method removeLabelHtml(uID)
var lbl = document.getElementById("lbl_1_" + uID);
if (lbl) lbl.innerText = '';
lbl = document.getElementById("lbl_2_" + uID);
if (lbl) lbl.innerText = '';
end
override virtual method getArrowedWidgetFromPoint(point)
var elems = [];
var styles = [];
var widget = this;
var board = this.board;
while(widget && !(widget.isa('core.lyt:ControlGroupLayout') || widget.isa('core.lyt:InteractorLayout'))) {
var st = widget.elem.style;
elems.push(st);
styles.push(st.visibility);
st.visibility = 'hidden';
var prev = widget;
widget = board.getWidgetFromPoint(point);
if (widget && widget.id == prev.id) break;
}
for (var len = elems.length, i = len - 1; i>= 0; i--) elems[i].visibility = styles[i];
return widget;
end
<@doc scope="private">
Starts a shape rename operation
virtual method startRename()
var attr = ISA(base, 'gml2:Button', 'gml2:PlainText', 'gml2:Hyperlink') ? 'value' : 'label';
if (base[attr] && base[attr].indexOf('=') == 0) return;
if (!RULE('canRename', base.unit, this.boardAspect, base)) return;
var diagram = this.getDiagram();
var board = diagram.board;
var crec = $WIN.getBoardClientRect();
var cpos = board.offsetToAbsolute(this.elem, {x:1, y:1});
var scrollTop = board.editbox.scrollTop;
var scrollLeft = board.editbox.scrollLeft;
if (diagram.getWindow().base.isa('gml2:Popup')) {
var offset = board.getOffset();
cpos.x += offset.offsetX;
cpos.y += offset.offsetY + 20; // The board offset plus the model tabs height
}
var moveLeft = BVAL(base.indent, true) ? this.labelWidth : 0;
if (attr == 'value') moveLeft = 0;
else attr = base.hasProperty('label') ? 'label' : 'name'; // It would be much better to use the property's getter function
var data = {
object: base,
graphic: this,
attr: attr,
callback: board.endRename,
delegate: this,
select: true,
x: cpos.x + crec.x - scrollLeft - moveLeft, centerX:false,
y: cpos.y + crec.y - scrollTop, centerY:false,
w: 100,
h: 8
};
board.textedit.show(data);
end
override virtual method canApplayRect(x, y, w, h)
if (!ISA(base, 'gml2:DateTimePicker')) return true;
return w >= this.minWidth;
end